赞
踩
单片机IO口配置
要用Windows系统,(XP 32bit亦可)。下载好SerialChart-0.3.4。
我使用的是Keil MDK 4 + STM32CubeMX。
SerialChart配置文件:
- [_setup_]
- port=COM9
- baudrate=115200
-
- width=1000
- height=400
- background_color = white
-
- grid_h_origin = 0
- grid_h_step = 10
- grid_h_color = #EEE
- grid_h_origin_color = #000
-
- grid_v_origin = 0
- grid_v_step = 10
- grid_v_color = #EEE
- grid_v_origin_color = #000
-
- [_default_]
- min=-8
- max=8
-
- [interval]
- color=transparent
- min=0
- max=100000
-
- [InVolt]
- color=blue
-
- [InCurr]
- color=red
-
- [InPwr]
-
- [OutVolt]
- color=black
-
- [OutCurr]
- color=orange
-
- [OutPwr]
-
-
- [an3]
- color=transparent
- min=0
- max=1023
[_setup_]里:port口请选择正确的COM口,打开设备管理器确认,或者打开串口调试助手(我使用的是ATK-XCOM V2.0),即可查看对应的COM口。波特率baudrate=115200,这个参数要和STM32的对应。
[_default_]是默认参数的大小。这个范围外的界面无法显示。
[interval]以及以下的就是数据的配置,数据的名称可自由配置。[interval]是第一列数据。[InVolt]是第二列数据。[InCurr]是第三列数据。以此类推。因为当时我用这个配置文件,显示输入电流、输入电压、输出电流、输出电压,所以用这个英文名字。可以随意改的,与数据显示无关系的。
我使用的数据是:第一列是时间戳,第二列开始是CH1,第三列是CH2。
例子:SerialChart会显示一包数据:20180110083138,1.2931,0.0758
其中第一个数据是时间戳,指当前时刻是2018年1月10日8:31:38。第二个数据是CH1=1.2931V,第三个数据是CH2=0.0758V。
另外要注意在配置ADC_DMA时候,DMA要配置成Circular才可以调用HAL_ADC_Start_DMA()。如果还是DMA Mode Normal,会进入硬件hardfault_handler。不知道为什么。
参数声明:
- float b_PirRaw,b_PirFltr;
- char s_PirRaw[10];
- char s_PirFltr[10];
-
- uint32_t b_date, b_month, b_year, b_hour, b_minute, b_second, b_day;
- char s_time[25];
- char a_date[2], a_month[2], a_year[4], a_hour[2], a_minute[2], a_second[2];
-
- int main(void)
- {
-
- while (1)
- {
-
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
- if(flag_100ms==1)
- {
- flag_100ms=0;
- SerialDisplay(); //数据通过串口发送出去
- }
- if(flag_1s==1)
- {
- flag_1s=0;
- UpdateDateTime(); //更新时间
- }
- }
- /* USER CODE END 3 */
-
- }
-
- void SerialDisplay(void)
- {
- s_time[0] = a_year[0];
- s_time[1] = a_year[1];
- s_time[2] = a_year[2];
- s_time[3] = a_year[3];
- s_time[4] = a_month[0];
- s_time[5] = a_month[1];
- s_time[6] = a_date[0];
- s_time[7] = a_date[1];
- s_time[8] = a_hour[0];
- s_time[9] = a_hour[1];
- s_time[10] = a_minute[0];
- s_time[11] = a_minute[1];
- s_time[12] = a_second[0];
- s_time[13] = a_second[1];
- s_time[14] = '\0';
-
- float2str(b_PirRaw, 2, s_PirRaw); //将float转换为str
- float2str(b_PirFltr, 2, s_PirFltr); //将float转换为str
-
- strcpy(a_UartTxBuf, s_time); //将s_time复制至a_UartTxBuf
- strcat(a_UartTxBuf, ","); //这句语句效果是a_UartTxBuf += ","
- strcat(a_UartTxBuf, s_PirRaw); //这句语句效果是a_UartTxBuf += s_PirRaw
- strcat(a_UartTxBuf, ",");
- strcat(a_UartTxBuf, s_PirFltr);
- strcat(a_UartTxBuf, "\r\n"); //一个数据包的结尾是"\r\n",同时strlen计算字符串长度是计算到\r\n
-
- HAL_UART_Transmit(&huart1, (uint8_t*)a_UartTxBuf, strlen(a_UartTxBuf), 100); //发送数据
-
- }
以上转换时间那几行真的不怎么优雅……
浮点数转换字符串。这代码我是复制的,来自https://www.cnblogs.com/gleam/p/3607984.html
- /**
- * @brief convert float to string
- * @param
- * @usage char buf[128];
- * printf("%s\n", float2str((float)1234.56789, -2, buf));
- * @retval None
- */
- char * float2str(float val, int precision, char *buf)
- {
- char *cur, *end;
-
- sprintf(buf, "%.4f", val);
- if (precision < 4) {
- cur = buf + strlen(buf) - 1;
- end = cur - 4 + precision;
- while ((cur > end) && (*cur == '0')) {
- *cur = '\0';
- cur--;
- }
- }
-
- return buf;
- }
每秒要执行一次这代码,更新本机时间。
-
- /*
- * @brief UpdateDateTime
- * input param: none
- * output param: none
- * relevent param: b_date b_month b_year b_hour b_minute b_second
- * must be execute every 1 second
- */
- void UpdateDateTime(void)
- {
- b_second++;
- if(b_second>=60)
- {
- b_second = 0;
- b_minute++;
- if(b_minute>=60)
- {
- b_minute = 0;
- b_hour++;
- if(b_hour>=24)
- {
- b_hour = 0;
- b_date++;
- if((b_date>=29)&&(b_month==2))
- {
- b_date = 1;
- b_month++;
- }
-
- if((b_date>=30)&&(b_month==2)&&(b_year%4==0))
- {
- b_date = 1;
- b_month++;
- }
- else if((b_date>=29)&&(b_month==2)&&(b_year%4!=0))
- {
- b_date = 1;
- b_month++;
- }
- else if((b_date>=31)&&((b_month==4)||(b_month==6)||(b_month==9)||(b_month==11)))
- {
- b_date = 1;
- b_month++;
- }
- else if((b_date>=32)&&((b_month==1)||(b_month==3)||(b_month==5)||(b_month==7)||(b_month==8)||(b_month==10)||(b_month==12)))
- {
- b_date = 1;
- b_month++;
- if(b_month>=13)
- {
- b_month = 1;
- b_year++;
- }
- }
- }
- }
- }
-
- a_year[0] = b_year/1000 + '0';
- a_year[1] = b_year%1000/100 + '0';
- a_year[2] = b_year%100/10 + '0';
- a_year[3] = b_year%10 + '0';
-
- a_month[0] = (uint8_t)b_month/10 + '0';
- a_month[1] = (uint8_t)b_month%10 + '0';
-
- a_date[0] = (uint8_t)b_date/10 + '0';
- a_date[1] = (uint8_t)b_date%10 + '0';
-
- a_hour[0] = (uint8_t)b_hour/10 + '0';
- a_hour[1] = (uint8_t)b_hour%10 + '0';
-
- a_minute[0] = (uint8_t)b_minute/10 + '0';
- a_minute[1] = (uint8_t)b_minute%10 + '0';
-
- a_second[0] = (uint8_t)b_second/10 + '0';
- a_second[1] = (uint8_t)b_second%10 + '0';
-
- }
以上看到本程序使用的数据包格式是:
<Timestramp>,<ch1>,<ch2>\r\n
即实现了带时间戳的双通道数据显示。
如果需要显示4通道,可以按照这样的格式:
<Timestramp>,<ch1>,<ch2>,<ch3>,<ch4>\r\n
如果需要显示更多的数据,可以按照这样的格式:
<Timestramp>,<ch1>,<ch2>,<ch3>,<ch4>,<ch5>,<ch6>,...,<chn>\r\n
也可以不发送第一列时间戳,但要在配置文件中删除[interval]
共享了工程:
链接: https://pan.baidu.com/s/1CQk6l4ziFMHXGxQEBbF_OA 提取码: aey4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。