当前位置:首页 > 学习资源 > 讲师博文 > 嵌入式系统是现代科技领域中的关键组成部分,贯穿于各个行业,从汽车到医疗设备

嵌入式系统是现代科技领域中的关键组成部分,贯穿于各个行业,从汽车到医疗设备 时间:2024-02-19      来源:华清远见

作为一名嵌入式工程师,在学习和工作中肯定会遇到很多相同的程序问题,这时候我们就需要把一下自己的一些积累的代码,copy过来直接拿来用或者简单拿来修改修改使用,本文将介绍几个实用的嵌入式C程序示例,并提供相应的代码解析,帮助读者更好地理解和应用这些示例。 代码以实用和帮助理解一些现象为主,如有缺陷,欢迎指出。

1. 日志时间的写入

下面程序实现:将当前的时间写入到time.txt的文件中,如果ctrl+c退出之后,在再次执行支持断点续写。在一些日志文件的写入时,可以选择在后面填写当前的时间。

#include <stdio.h>

#include <string.h>

#include <time.h>

#define PRINT_ERR(errmsg) \

   do {                 \

       perror(errmsg);   \

       printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);\

       return -1;       \

   } while (0)

int get_file_line(FILE* fp)

{

   int line=0;

   char s[30];

   // 循环读文件

   while (fgets(s, 30, fp) != NULL) {

       if (s[strlen(s) - 1] == '\n')

           line++;

  }

   return line;

}

int main(int argc, const char* argv[])

{

   time_t ts, ots;

   struct tm* tm;

   char tim[50] = { 0 };

   FILE* fp;

   int line = 0;

   if ((fp = fopen("./time.txt", "a+")) == NULL)

       PRINT_ERR("fopen error");

   

   line = get_file_line(fp);

   ts = ots = 0;

   while (1) {

       if ((ts = time(NULL)) == -1)

           PRINT_ERR("time error");

       if (ts != ots) {

           ots = ts;

           if ((tm = localtime(&ts)) == NULL)

               PRINT_ERR("localtime error");

           snprintf(tim, sizeof(tim), "%d.%d-%02d-%02d %02d:%02d:%02d\n",

               line++, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,

               tm->tm_hour, tm->tm_min, tm->tm_sec);

           fputs(tim, fp);

           fflush(fp);

      }

  }

   fclose(fp);

   return 0;

}

程序现象:

2. 将十六进制字符串转换为整型数字

下面程序实现:将16进制的字符串转换为10进制的数字。

#include <stdio.h>

int hex_to_int(char hex[]) {

   int decimal = 0;

   int digit_value;

   int i = 0;

   // 计算每个十六进制位的值,并将其相加

   while (hex[i] != '\0') {

       char current_char = hex[i];

       if (current_char >= '0' && current_char <= '9') {

           digit_value = current_char - '0';

      } else if (current_char >= 'a' && current_char <= 'f') {

           digit_value = current_char - 'a' + 10;

      } else if (current_char >= 'A' && current_char <= 'F') {

           digit_value = current_char - 'A' + 10;

      } else {

           printf("Invalid hexadecimal string.\n");

           return 0;

      }

       decimal = decimal * 16 + digit_value;

       i++;

  }

   return decimal;

}

int main() {

   char hex_string[] = "ABCD";  // 十六进制字符串

   int decimal = hex_to_int(hex_string);  // 将十六进制字符串转换为整型数字

   printf("Decimal: %d\n", decimal);  // 打印转换后的十进制数

   return 0;

}

代码运行现象:

3.给BMP格式的图片打马赛克

下面程序实现对BMP格式的图片打马赛克:

#include <stdio.h>

#include <stdlib.h>

typedef struct {

   unsigned char b;

   unsigned char g;

   unsigned char r;

} RGB_t;

#define MOSIC_WIDTH 10

#define MOSIC_HIGH 10

#define PRINT_ERR(errmsg) \

   do {                 \

       perror(errmsg);   \

       printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);\

       return -1;       \

   } while (0)

int main(int argc, const char* argv[])

{

   FILE* fp;

   unsigned int size, offset, width, high;

   unsigned short pix;

   // 1.对命令行参数校验

   if (argc != 2) {

       fprintf(stderr, "input error,try again\n");

       fprintf(stderr, "usage: ./a.out xxx.bmp\n");

       return -1;

  }

   // 2.打开图片

   if ((fp = fopen(argv[1], "r+")) == NULL)

       PRINT_ERR("fopen error");

   // 3.读取图片信息

   fseek(fp, 2, SEEK_SET);

   fread(&size, 4, 1, fp);

   printf("size = %d\n", size);

   fseek(fp, 4, SEEK_CUR);

   fread(&offset, 4, 1, fp);

   printf("offset = %d\n", offset);

   fseek(fp, 18, SEEK_SET);

   fread(&width, 4, 1, fp);

   printf("width = %d\n", width);

   fread(&high, 4, 1, fp);

   printf("high = %d\n", high);

   fseek(fp, 2, SEEK_CUR);

   fread(&pix, 2, 1, fp);

   printf("pix = %d\n", pix);

   // 4.打马赛克

   RGB_t(*img)[width] = malloc(width * high * (pix / 8));

   // 4.1将图片的数据读出来

   fseek(fp, 54, SEEK_SET);

   for (int i = 0; i < high; i++) {

       for (int j = 0; j < width; j++) {

           fread(&img[i][j], sizeof(RGB_t), 1, fp);

      }

  }

   // 4.2打马赛克

   for (int i = 0; i < (high / MOSIC_HIGH) * MOSIC_HIGH; i += MOSIC_HIGH) {

       for (int j = 0; j < (width / MOSIC_WIDTH) * MOSIC_WIDTH; j += MOSIC_WIDTH) {

           for (int x = 0; x < MOSIC_HIGH; x++) {

               for (int y = 0; y < MOSIC_WIDTH; y++) {

                   img[i + x][j + y] = img[i][j];

              }

          }

      }

  }

   // 4.3将图片的数据写入到文件中

   fseek(fp, 54, SEEK_SET);

   for (int i = 0; i < high; i++) {

       for (int j = 0; j < width; j++) {

           fwrite(&img[i][j], sizeof(RGB_t), 1, fp);

      }

  }

   return 0;

}

程序现象:

4.对BMP程序打马赛克进阶

下面程序利用C++ QT程序将上面的功能进行了拓展,可以实现界面选择图片处理,当你理解了上面的程序之后,利用C++结合QT就能快速上手做出一个图像处理的demo程序。

mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <QMainWindow>

#include <QPushButton>

#include <QImage>

#include <QLabel>

#include <QFileDialog>

class MainWindow : public QMainWindow

{

   Q_OBJECT

public:

   MainWindow(QWidget *parent = nullptr);

   ~MainWindow();

private slots:

   void openImage();

   void processImage();

   void saveImage();

private:

   QLabel *imageLabel;  // 用于显示图像的控件

   QImage originalImage;  // 原始图像

   QImage processedImage;  // 处理后的图像

};

#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])

{

   QApplication a(argc, argv);

   MainWindow w;

   w.show();

   return a.exec();

}

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)

  : QMainWindow(parent)

{

   this->setFixedSize(1250,800);

   imageLabel = new QLabel(this);

   setCentralWidget(imageLabel);

   QPushButton *openButton = new QPushButton("打开图片", this);

   connect(openButton, &QAbstractButton::clicked, this, &MainWindow::openImage);

   QPushButton *processButton = new QPushButton("处理图片", this);

   connect(processButton, &QAbstractButton::clicked, this, &MainWindow::processImage);

   processButton->move(150,0);

   QPushButton *saveButton = new QPushButton("保存图片", this);

   connect(saveButton, &QAbstractButton::clicked, this, &MainWindow::saveImage);

   saveButton->move(300,0);

}

MainWindow::~MainWindow()

{

}

void MainWindow::openImage()

{

   QString imagePath = QFileDialog::getOpenFileName(this, "选择图像", "", "BMP 图像 (*.bmp)");

   if (!imagePath.isEmpty())

  {

     originalImage.load(imagePath);

     imageLabel->setPixmap(QPixmap::fromImage(originalImage));

     imageLabel->adjustSize();

  }

}

void MainWindow::processImage()

{

   if (!originalImage.isNull())

      {

           processedImage = originalImage.copy();  // 复制原始图像进行处理

           int gridSize = 16;  // 马赛克块的大小

           for (int x = 0; x < processedImage.width(); x += gridSize)

          {

               for (int y = 0; y < processedImage.height(); y += gridSize)

              {

                   QRgb averageColor = processedImage.pixel(x, y);

                   for (int i = 0; i < gridSize; i++)

                  {

                       for (int j = 0; j < gridSize; j++)

                      {

                           int newX = qMin(x + i, processedImage.width() - 1);

                           int newY = qMin(y + j, processedImage.height() - 1);

                           processedImage.setPixel(newX, newY, averageColor);

                      }

                  }

              }

          }

           imageLabel->setPixmap(QPixmap::fromImage(processedImage));

           imageLabel->adjustSize();

  }

}

void MainWindow::saveImage()

{

   if (!processedImage.isNull())

      {

           QString savePath = QFileDialog::getSaveFileName(this, "保存图像", "", "BMP 图像 (*.bmp)");

           if (!savePath.isEmpty())

          {

               processedImage.save(savePath);

          }

      }

}

程序现象:

5.在linux中获取本地IP的程序

下面程序是在linux中获取本地IP的程序:

#include <stdio.h>

#include <ifaddrs.h>

#include <netinet/in.h>

#include <string.h>

#include <arpa/inet.h>

#define MAX_IP_COUNT 3

#define IP_ADDR_LEN INET_ADDRSTRLEN

int get_local_ip(char ipList[MAX_IP_COUNT][IP_ADDR_LEN]) {

   struct ifaddrs *ifAddrStruct;

   char ipAddr[IP_ADDR_LEN];

   void *tmpAddrPtr;

   int ipCount = 0;

   // 获取网络接口列表

   if (getifaddrs(&ifAddrStruct) == -1) {

       perror("getifaddrs");

       return 0;

  }

   

   // 遍历网络接口列表

   while (ifAddrStruct != NULL) {

       if (ifAddrStruct->ifa_addr->sa_family == AF_INET) {

           tmpAddrPtr = &((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;

           inet_ntop(AF_INET, tmpAddrPtr, ipAddr, IP_ADDR_LEN);

           

           // 排除回环地址

           if (strcmp(ipAddr, "127.0.0.1") != 0) {

               if (ipCount < MAX_IP_COUNT) {

                   memcpy(ipList[ipCount], ipAddr, IP_ADDR_LEN);

                   ipCount++;

              } else {

                   break;

              }

          }

      }

       ifAddrStruct = ifAddrStruct->ifa_next;

  }

   freeifaddrs(ifAddrStruct);

   return ipCount;

}

int main() {

   char ipAddrList[MAX_IP_COUNT][IP_ADDR_LEN];

   int addrCount;

   

   memset(ipAddrList, 0, sizeof(ipAddrList));

   addrCount = get_local_ip(ipAddrList);

   if (addrCount > 0) {

       printf("Server Local IP:\n");

       for (int i = 0; i < addrCount; i++) {

           printf("%d: %s\n", i+1, ipAddrList[i]);

      }

  } else {

       printf("No local IP address found.\n");

  }

   

   return 0;

}

程序现象:

上一篇:嵌入式工程师之路:成为顶级专业人士的关键步骤

下一篇:贝叶斯估计和最大似然估计的区别

戳我查看2020年嵌入式每月就业风云榜

点我了解华清远见高校学霸学习秘籍

猜你关心企业是如何评价华清学员的

干货分享
相关新闻
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2024 北京华清远见科技发展有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部