引言

作为郑州的嵌入式新人,最近接到两个任务,第一个是根据门禁设备的驱动程序写出一个接受串口数据的应用,这个串口用于连接读卡器等设备。第二个是把libpng移植到门禁设备上,由于我们的门禁设备只支持jpg格式的图片,因此要用这个库把png图片转为raw格式,然后再转换为jpg格式。第一个任务以及完成,今天先整理第一个任务。

开发过程及源码

首先在主程序中重新开一个串口任务

#if defined(USING_UART_Receive_ENABLE)   #define UART_RECEIVE_PRI 31printf("uart_receive test.\n");aos_task_t uart_receive_thread;ret = aos_task_new_ext(&uart_receive_thread, "uart_receive", uart_reader_task, NULL, 10*1024, UART_RECEIVE_PRI);
#endif

在uart_reader_task函数中进行串口的初始化,配置等操作,首先进行引脚复用,然后使能时钟,开启相应引脚功能,由于是多线程任务,为了保证数据的完成行,创建信号量进行处理。在本任务中主要需要关注的是csi_uart_initialize(),csi_uart_config(),csi_uart_receive()。

void uart_reader_task(void *paras)
{   uint8_t *p;int i=0;int ret=-1;int rece_size =0;int cnt;device_event_t * evt;drv_pinmux_config(OTP_MUX,UART1_MUX);drv_disable_uart_clock(1);drv_uart_clk_sel(1, CLK_SEL_PLL);drv_enable_uart_clock(1);drv_set_uart_freq(1,10,275);ret = krhino_sem_create(&uart_reader_sem, "UART-READER-SEM", 0);if (ret != RHINO_SUCCESS) {return ret;}handle = csi_uart_initialize(1, uart_receive_event_cb);ret = csi_uart_config(handle, 9600,UART_PARITY_NONE,UART_STOP_BITS_1, UART_DATA_BITS_8);csi_uart_receive(handle,NULL,0);while(1){ret = krhino_sem_take(&uart_reader_sem, RHINO_WAIT_FOREVER);if (ret != RHINO_SUCCESS) {k_err_proc(ret);}if(uart_reader_state == UART_READER_STATE_FULL){evt = device_event_construct("open",DeviceEventTypeOperation);if(evt){evt->data =device_event_alloc(evt,16);p = evt->data;*p = 0x26;p++;*p = uart_reader_frame[9];p++;*p = uart_reader_frame[8];p++;*p = uart_reader_frame[7];device_event_notify(evt);}uart_reader_state = UART_READER_STATE_INIT;}}
//  ret = csi_uart_uninitialize(handle);
}

其中有意思的是在初始化配置的时候还能这样定义结构体数组,让我惊呆了(菜鸟新人看的代码少,没见过世面)这样的写法让代码看着更加整洁美观。到这一步串口已经配置好,相应的中断已经打开,众所周知,串口的接收主要靠中断完成,由于刚入行先从嵌入式应用做起,驱动我就不那么细看了,主要关心厂家给出的接口。

struct {uint32_t base;uint32_t irq;void *handler;
}
static const sg_uart_config[CONFIG_UART_NUM] = {{CSKY_UART0_BASE,  UART0_IRQn,  UART0_IRQHandler},{CSKY_UART1_BASE,  UART1_IRQn,  UART1_IRQHandler},{CSKY_UART2_BASE,  UART_CK804_IRQn,  UART_CK804_IRQHandler},{CSKY_UART3_BASE,  UART_CK805_IRQn,  UART_CK805_IRQHandler},
};int32_t target_uart_init(int32_t idx, uint32_t *base, uint32_t *irq, void **handler)
{if (idx >= CONFIG_UART_NUM) {return -1;}if (base != NULL) {*base = sg_uart_config[idx].base;}if (irq != NULL) {*irq = sg_uart_config[idx].irq;}if (handler != NULL) {*handler = sg_uart_config[idx].handler;}return idx;
}

在中断函数中进入相应的事件,由于是接收,进入 ck_uart_intr_recv_data(uart_priv);这个函数

void ck_uart_irqhandler(int idx)
{ck_uart_priv_t *uart_priv = &uart_instance[idx];ck_uart_reg_t *addr = (ck_uart_reg_t *)(uart_priv->base);uint32_t intr_state = addr->UART_FCR_IIR & 0xf;if (intr_state & IIR_INT_TX_EMPTY) {ck_uart_intr_send_empty(uart_priv);} else if (intr_state & IIR_INT_RX_THOLD) {ck_uart_intr_recv_data(uart_priv);} else if (intr_state & IIR_INT_UART_STOP) {ck_uart_intr_char_timeout(uart_priv);     //receive small data} else if (intr_state & IIR_INT_UART_PERR) {ck_uart_intr_process_error(uart_priv);}
}

在初始化串口的时候已经把回调函数注册进去了,在串口进入相应事件的时候会调用回调函数,我们根据状态在回调函数中对串口进行处理。在本项目中主要应用了UART_EVENT_RECEIVED这个事件,csi_uart_receive_query这个函数是从FIFO(First Input First Output的缩写,先入先出队列中)读取数据

static void uart_receive_event_cb(int32_t idx, uint32_t event)
{int rx_count;   switch (event) {case UART_EVENT_SEND_COMPLETE://     printf("send complete!!!!!!\r\n");break;case UART_EVENT_RX_TIMEOUT:uart_reader_state = UART_READER_STATE_INIT;break;case UART_EVENT_RECEIVE_COMPLETE:rx_count = drv_usi_usart_get_rx_count(handle);//   printf("rx_count  %d\n",rx_count);break;case UART_EVENT_RECEIVED:if(uart_reader_state != UART_READER_STATE_FULL){rx_count = csi_uart_receive_query(handle,uart_reader_buf,sizeof(uart_reader_buf));//   printf("rx_count  %d\n",rx_count);if(rx_count>0)uart_reader_read_frame(uart_reader_buf,rx_count);}break;default:break;}

读取数据后利用uart_reader_read_frame按照通信协议进行拼包,在拼包过程中一定要考虑全面,把各种边界条件考虑进去,这里我把独创源码进行分享了,如果感觉有用的话记得点赞评论哦~

static int uart_reader_read_frame(uint8_t * data,int rx_count)
{int i=0;while(i<rx_count){if(uart_reader_state == UART_READER_STATE_INIT){if(data[i]!=0x20){i++;continue;}uart_reader_state = UART_READER_STATE_HEAD;uart_reader_len = 0;i++;uart_reader_off = 0;if((rx_count-i)<3){if((rx_count-i)>0){//                  printf("(rx_count-i):%diiiii\n",(rx_count-i));memcpy(&uart_reader_frame[uart_reader_off],&data[i],(rx_count-i));uart_reader_off += (rx_count-i);}return;}}else if(uart_reader_state == UART_READER_STATE_HEAD){//          printf("uart_reader_off:%d\n",uart_reader_off);memcpy(&uart_reader_frame[uart_reader_off],&data[i],3-uart_reader_off);uart_reader_len = uart_reader_frame[2];//           printf("uart_reader_len:%d\n",uart_reader_len);uart_reader_len+=2;uart_reader_state = UART_READER_STATE_DATA;i+=(3-uart_reader_off);uart_reader_off=3;if((rx_count-i)<uart_reader_len){//              printf("(rx_count-i):%d\n",(rx_count-i));if((rx_count-i)>0){//                  printf("(rx_count-i):%dhhhh\n",(rx_count-i));memcpy(&uart_reader_frame[uart_reader_off],&data[i],(rx_count-i));uart_reader_off += (rx_count-i);}return ;}//          printf("begain rev data\n");}else if(uart_reader_state == UART_READER_STATE_DATA){int j;//          printf("uart_reader_off:%d\n",uart_reader_off);memcpy(&uart_reader_frame[uart_reader_off],&data[i],uart_reader_len+3-uart_reader_off);i+=(uart_reader_len+3-uart_reader_off);uart_reader_off = 0;printf("receive:");for(j=0; j<uart_reader_len+3; j++){printf("%2.2x",uart_reader_frame[j]);}printf("\n");j = krhino_sem_give(&uart_reader_sem);if (j != RHINO_SUCCESS) {return;}uart_reader_state = UART_READER_STATE_FULL;}else{printf("receive complete????????\r\n");}}}

到这里一个完整的串口数据包以及从串口中获得,剩下的就可以提取想用的信息进行处理了。

牵扯到的小知识整理

小结

这个任务共做了4天,难度主要在于接口文档不全,以及ALIOS的资料较少,通过这个任务对自己的C语言提升很大,代码基本上都可以看懂了,特别是利用指针在程序中传递数据,指针在传递数据的时候可以这样理解,你向某个地址放东西,如果你知道这个地址,那么在哪个文件中都可以取这个数据,因为数据放的地址已经知道了,很灵活。就是把脑子的概念扭转过来,对习惯对地址操作的思维方式。接下来开始移植libpng,下篇文章再见!

基于alios系统门禁uart串口应用编写相关推荐

  1. 【毕业设计】基于单片机的门禁系统 - 嵌入式 物联网

    文章目录 1 简介 2 课题背景 3 详细设计 3.1 整体设计方案 3.2 功能模块 3.3 软件设计 4 实现效果 5 部分实现代码 6 最后 1 简介 Hi,大家好,这里是丹成学长,今天向大家介 ...

  2. 【毕业设计】基于RFID的门禁系统 - 单片机 物联网 嵌入式 stm32

    文章目录 1 简介 2 绪论 2.1 课题背景与目的 3 射频识别 3.1 射频识别技术 3.2 射频识别模块 3.2.1 RFID模块 3.2.2 RFID模块组成 4 系统设计 4.1 系统架构 ...

  3. 物联网毕业设计 基于RFID的门禁系统

    文章目录 1 简介 2 绪论 2.1 课题背景与目的 3 射频识别 3.1 射频识别技术 3.2 射频识别模块 3.2.1 RFID模块 3.2.2 RFID模块组成 4 系统设计 4.1 系统架构 ...

  4. 【基于Arduino RFID门禁系统】

    基于Arduino RFID门禁系统 介绍 射频识别或RFID(Radio-Frequency Identification)是一种通过无线电信号进行自动识别,通过RFID标签检索和存储数据的方法. ...

  5. 基于JAVA政府机关门禁管理系统计算机毕业设计源码+系统+数据库+lw文档+部署

    基于JAVA政府机关门禁管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA政府机关门禁管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 ...

  6. 猿创征文|基于物联网的门禁与考勤系统_阿里云_2022

    1. 前言 当今社会是科学技术日新月异.飞速发展的信息时代.人们正感受着高科技给他们带来的极大方便和益处,同时,人们对于高科技服务于生活的要求也越来越高.但随着科技的发展,也带来了许多不安全的方面.例 ...

  7. java程序报告门禁系统_基于JAVA的门禁管理系统(含源文件).doc

    基于JAVA的门禁管理系统 学 生 姓 名: 学 院: 专 业: 班 级: 学 号: 指 导 教 师: 完 成 日 期: 摘 要 随着社会经济和科技的发展,IC卡技术已广泛地应用于各种行业,特别是公共 ...

  8. 【单片机毕业设计】【mcuclub-jj-050】基于单片机的门禁的设计

    最近设计了一个项目基于单片机的门禁系统,与大家分享一下: 一.基本介绍 项目名:门禁 项目编号:mcuclub-jj-050 单片机类型:STC89C52.STM32F103C8T6 具体功能: 1. ...

  9. 基于MFRC522的门禁系统的设计与实现

    目录 1.MFRC522简介 2.概述 3.硬件设计 4.软件设计 5.实物测试 1.MFRC522简介 MFRC522是高度集成的非接触式(13.56MHz)读写卡芯片.此发送模块利用调制和解调的原 ...

最新文章

  1. TinkerNode NB-IoT物联网开发板(NB-IoT专栏—拓展篇3)
  2. 深度分析typedef--定义自己的数据类型
  3. TCP/IP详解学习笔记(12)-TCP的超时与重传
  4. 配置Vm box虚拟机
  5. mongodb 企业版_MongoDB 凉了?
  6. DASH直播平台的搭建
  7. MyBatis——动态SQL讲解
  8. nginx 目录讲解
  9. Nginx 内置绑定变量的介绍
  10. 真格量化——50期权历史波动率策略
  11. 信数金服:决策模型的迭代
  12. 【离散数学】图的着色与对偶图
  13. Java工作笔记-使用Maven创建多模块项目
  14. linux打开文件异常
  15. 学习Python的好去处,微信公众号“Python小屋”
  16. Panoply软件安装
  17. java,python,scala发送http请求
  18. 江苏华罗庚中学2021高考成绩查询,2021年常州各高中高考成绩排名及放榜最新消息...
  19. Android App Bundle: 最新改进和 Google Play 新应用计划
  20. python分词统计词频_-用python找出一篇文章中词频最高的20个单词

热门文章

  1. chrony时间同步
  2. [正则表达式]可以为空值,不为空则要验证格式
  3. Mathcad_excel数据处理
  4. windows 和 Linux 查看IP属性(ipconfig,ifconfig)
  5. 牛客网SQL 进阶篇刷题
  6. 快速将PDF图片转成PPT
  7. 英飞凌TC275芯片开发笔记
  8. Win11连接WiFi后显示“无Internet,安全”
  9. Integer.valueOf、intValue、Integer.parseInt使用
  10. IgH详解六、IgH命令行工具使用