zoukankan      html  css  js  c++  java
  • 新唐单片机项目总结

    最近做了两个单片机项目,新唐的029和mini58ZDE的MCU,都是cortex-M0,一个厂家所以API基本一致,大致了解了串口中断及定时器功能以及ADC采样相关的编程内容。
    4G项目即mini58zde,主要是从GPS中读数据然后从另外一个串口转发出去
     
     
    GPS模块  ------ 串口1接收 ----数据处理组包 -----串口0发送------上位机
     
    GPS模块是不断地有数据来,数据格式为
    $GNRMC,014053.00,A,3205.65222,N,11853.26056,E,0.038,,030817,,,D,V*18
    $GNGGA,014053.00,3205.65222,N,11853.26056,E,2,14,0.81,52.6,M,3.1,M,,*41
    $GNGSA,A,3,01,09,11,16,08,30,28,,,,,,1.36,0.81,1.09,1*0A
    $GNGSA,A,3,03,07,08,01,02,04,13,,,,,,1.36,0.81,1.09,4*08
    $GPGSV,4,1,16,01,47,176,41,04,12,058,,07,66,274,,08,55,026,30,0*63
    $GPGSV,4,2,16,09,10,223,30,10,03,059,28,11,72,198,46,16,16,098,45,0*6F
    $GPGSV,4,3,16,17,02,245,23,22,05,152,18,23,02,197,,27,23,049,18,0*65
    $GPGSV,4,4,16,28,17,303,37,30,36,311,29,42,43,137,42,50,43,137,42,0*67
    $BDGSV,3,1,10,01,48,143,43,02,37,232,39,03,53,196,43,04,33,121,35,0*78
    $BDGSV,3,2,10,05,16,252,,07,76,112,44,08,69,219,44,10,74,327,,0*7E
    $BDGSV,3,3,10,13,43,220,42,17,50,110,,0*75
    $GNTXT,1,1,01,ANTENNA OPEN*3B
    主要处理的数据是GNRMC和GNGGA,用了状态机的方法判断前面GMRMC/GNGGA之后直接判断是否是 ‘*’,因为逐个判断状态太多,很复杂而且容易出错,读取到 * 之后,再读校验位,校验成功的话,将数据拷贝到 处理缓冲区置标志位,在主程序中检测标志位,然后处理数据,更新数据
    串口0 既要接受命令也要返回数据,串口0的数据接受为固定长度的,在这里也使用了状态机,提取出命令码之后,将命令码写到命令队列中,这样就能及时响应下一个命令,不用死等,数据接收与数据处理独立运行,不会造成高耦合的现象
     
    串口0 接收数据提取命令码---------压入命令队列 POP(中断中实现)
     
    串口1 接受提取有效数据-------------更新GPS数据结构体(中断中实现)
     
    主程序 读取命令队列----------------出列PUSH ,根根不同的命令将GPS数据组包通过串口0发出去。
    主程序中使能看门狗,使用定时器喂狗。
    开发中遇到的一些问题:
    1.设计思路有问题,没理清流程,一开始以为接受到命令码马上处理,造成串口0一直要等待
    2.看门狗操作寄存器是写保护,要先解保护才能操作,厂家给的示例不对,造成看门狗使能失败,喂狗失败。
    3.状态机使用出错,状态太多,两条命令混合处理,造成代码混乱,很难理清。
    4.铁塔协议花了很久才明白是怎么一回事,要多看代码才行。
    5.内部时钟的配置,要根据实际情况来,没有外部时钟就不能用,
     
    029电源控制模块:
    电源充放电管理的一个小模块,几个条件限制充放电
    低于5度不充电,电压低于6.1V或者放电时间到了20MIN不放电
    使用了GPIO的中断 确定什么时候开始放电,电源关闭,下降沿触发,电池开始放电。重新上电,上升沿,电池可以开始充电。代码很简单主要是ADC采样还有定时器中断的问题,
    电压和温度都是通过ADC采样转换实现的,使用内部温度,一个管脚配置成温度传感器,然后进行ADC采样,电压基准源采用的是3.3V,这个项目没有串口,打印会造成很多异常,debug下正常但正常跑起来却有问题,所以调试时尽量少用或者不用printf,整个程序很简单,就是控制GPIO口
     
    开发中遇到的一些问题:
    1.添加printf造成程序异常,定时器异常
    2.一上电就进行ADC采样不对,电压还没有升上来,采样的值很小,等待10ms之后采样值就对了
    3.float 数据计算及比较要注意
    void UART1_RT_STATE(uint8_t u8InChar)
    {
    		uint8_t	TempBuf[3]= {0};
    		uint8_t	CheckSum = 0;
    					switch(x_RecvState)
    				 { 
    					 case WaitingForHeads:
    						 if(u8InChar == '$')
    						 {
    							 UART1_Rx_buff[0] = u8InChar;
    								x_RecvState = WaitingForG;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForG:
    						 if(u8InChar == 'G')
    						 {
    							 UART1_Rx_buff[1] = u8InChar;
    							 x_RecvState = WaitingForN;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForN:
    					 if(u8InChar == 'N')
    						 {
    							 UART1_Rx_buff[2] = u8InChar;
    							 x_RecvState = WaitingForG_R;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForG_R:
    							if(u8InChar == 'G')
    						 {
    							 UART1_Rx_buff[3] = u8InChar;
    							 x_RecvState = WaitingForG_2;
    						 }
    							else if(u8InChar == 'R')
    						 {
    							 UART1_Rx_buff[3] = u8InChar;
    							 x_RecvState = WaitingForM;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForG_2:
    							if(u8InChar == 'G')
    						 {
    							 UART1_Rx_buff[4] = u8InChar;
    							 x_RecvState = WaitingForA;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForM:
    							if(u8InChar == 'M')
    						 {
    							 UART1_Rx_buff[4] = u8InChar;
    							 x_RecvState = WaitingForC;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForC:
    							if(u8InChar == 'C')
    						 {
    							 UART1_Rx_buff[5] = u8InChar;
    							 x_RecvState = WaitingForRs;
    							 rcv_count = 6;
    							 gps_flag = RMC;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForA:
    							if(u8InChar == 'A')
    						 {
    							 UART1_Rx_buff[5] = u8InChar;
    							 x_RecvState = WaitingForGs;
    							  rcv_count = 6;
    							 gps_flag = GGA;
    						 }
    						 else
    						 {
    							 x_RecvState = WaitingForHeads;
    							 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 }
    						 break;
    					 case WaitingForRs:	
    							if(u8InChar != '*')
    						 {
    							 UART1_Rx_buff[rcv_count++] = u8InChar;
    							 if(rcv_count > 65)
    							 {
    									x_RecvState = WaitingForHeads;
    									memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    							 }
    							 else
    							 x_RecvState = WaitingForRs;
    						 }
    						 else
    						 {
    							 if(rcv_count != 65)
    							 {
    								 if(rcv_count == 37)
    								 {		 
    									 gps_flag = NOUSE;
    									 DATA_ANY = 1;
    								 }
    									x_RecvState = WaitingForHeads;
    									memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    							 }	
    							else
    							{
    						 	  UART1_Rx_buff[rcv_count++] = u8InChar;								
    							  x_RecvState = WaitingForChsum_1;
    							}
    						 }	 
    						 break;
    					 case WaitingForGs:	
    							if(u8InChar != '*')
    						 {
    							 UART1_Rx_buff[rcv_count++] = u8InChar;
    							 if(rcv_count > 68)
    							 {
    									x_RecvState = WaitingForHeads;
    									memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    							 }
    							 else
    							 x_RecvState = WaitingForGs;
    						 }
    						 else
    						 {
    							 if(rcv_count != 68)
    							 {
    								 if(rcv_count == 36)
    								 {		 
    									 gps_flag = NOUSE;
    									 DATA_ANY = 1;
    								 }
    									x_RecvState = WaitingForHeads;
    									memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    							}	
    							else
    							{
    									UART1_Rx_buff[rcv_count++] = u8InChar;								
    									x_RecvState = WaitingForChsum_1;
    							}
    						 }	 
    						 break;
    	
    					 case WaitingForChsum_1:
    	//								printf("gf = %d
    ",gps_flag);
    
    							 UART1_Rx_buff[rcv_count++] = u8InChar;
    							 x_RecvState = WaitingForChsum_2;
    								break;
    					 case WaitingForChsum_2:
    							TempBuf[0]= UART1_Rx_buff[rcv_count-1];
    							TempBuf[1]=u8InChar;
    							TempBuf[2]=0;
    							CheckSum=strtoul(TempBuf,NULL,16);
    							UART1_Rx_buff[rcv_count++] = u8InChar;
    					 		Checkret = GpsChecksum(CheckSum);					 
    							 x_RecvState = WaitingForEnd_1;
    							break;
    
    					 case WaitingForEnd_1:
    							if(u8InChar == 0xD)
    						 {
    							 UART1_Rx_buff[rcv_count++] = u8InChar;
    							 x_RecvState = WaitingForHeads;
    							 if(Checkret)
    							 {
    								 #if 0
    								if(gps_flag == GGA)
    							P13 = 1;
    						if(gps_flag == RMC)
    							P13 = 0;
    						#endif
    									memcpy(UART1_Pr_buff,UART1_Rx_buff,rcv_count);						
    								  Checkret = 0;
    								  DATA_ANY = 1;
    							 }
    						 }
    						 x_RecvState = WaitingForHeads;
    						 rcv_count = 0;
    						 memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 break;
    					 default:
    						 rcv_count = 0;
    						 	x_RecvState = WaitingForHeads;
    							memset(UART1_Rx_buff,0,sizeof(UART1_Rx_buff));
    						 break;
    					 }			 
    }
    

      

  • 相关阅读:
    mysqldump备份数据
    windows上mysql5.7服务启动报错
    Java NIO:FileChannel数据传输
    HBase过滤器:SingleColumnValueFilter和FirstKeyOnlyFilter一起使用的问题
    Java自定义注解
    Kafka Connect使用入门-Mysql数据导入到ElasticSearch
    Kafka中使用Avro编码、解码消息
    堆和栈
    Java中基本数据类型byte,short,char,int,long,float,double 取值范围
    对快速排序的一点小探究
  • 原文地址:https://www.cnblogs.com/yinseyingji/p/7422815.html
Copyright © 2011-2022 走看看