很久以前,我是看到了项目LCD Smartie,特别适合下载机,自组服务器,不用外接显示器就知道电脑运行的一些参数,非常酷,一直想做一个,但是有几个原因没有制作:
这次做的是ch340的usb串口模块接STM8L051单片机,STM8L051负责串口转i2c,再接一个3.3v转5v ttl转换模块,再接到i2c转lcd1602转换板,最终接上lcd1602(5V)显示信息;
1.为什么不直接用stm8直连LCD1602? 主要是因为选的是5v的LCD1602模块,接转换板解决,为增强稳定性,使用5v-3.3v的TLL转换模块。
2. 为什么我把st-link单独放一边,因为STM8可以串口现在,但有条件限制的,要空白 IC+打开了bootloader功能,原则上新买的裸 IC 是符合的,但没有测过,不过我擦写FLASH后试过,串口可以使用,不过第一次用,你不调试的话可以直接在我的项目(点击文字查看)下的firmware固件用串口烧录就可以
原理图 (点击可以查看完整图)简单描述了部分器件的摆布情况,ch340串口模块省略没加,这里主要图示STM8L051串口和I2C接线部分,其他的有现成的模块:
首先放完整代码(点击查看)在这里,点击文字可以跳转到git项目。
上位机用的python, 理论上支持跨平台,不过我用虚拟机测发现磁盘信息读的不准,需要屏蔽掉;
STM8L051的MCU这边,有用到串口收发、看门狗恢复系统异常、I2C驱动LCD1602;
自己定义了一个串口协议,格式如下:
总长:35-bytes
结构: 头部+第1行显示数据+第2行显示数据+显示行数+检验和
结构长度:1-byte + 16-bytes + 16-bytes + 1-byte + 1-byte
校验和是前面不含头部数据的累加和,且只保留1-byte数据
LCD1602自定义了2个字符 下载速度使用"↓"(由于这个不是ascii码可以表示的,上位机用0xFE代替发送 ),上传速度使用"↑"(由于这个不是ascii码可以表示的,上位机用0xFF代替发送);
自定义字符在STM8L051程序里面需要每次开机都要写入LCD1602的CGRAM地址中,不属于厂家固化的编码,掉电后不稳定,且我自定义字符放在LCD1602的0x40 ~ 0x47和0x48 ~ 0x4f数据的地址中:
uint8_t upload_str[8]={0x04, 0x0E, 0x15, 0x04, 0x04, 0x04, 0x04, 0x00}; // char "↑"
uint8_t download_str[8]={0x04, 0x04, 0x04, 0x04,0x15, 0x0E, 0x04, 0x00}; //char "↓"
customer_word(upload_str, 0x40, 8); // upload_str set code 0x00
customer_word(download_str, 0x48, 8); // download_str set code 0x01
<<<<<<<<<<<<<<<<<<<<<<<<项目工程>>>>>>>>>>>>>>>>>>
不放完整代码了,可去项目git 的python_app文件夹下看,这里只要说明一下上位机一些可配置的部分,主要有4点注意的:
# ------------------- user config section --------------------------------------------------
refresh_cycle_time = 5 #refresh time, by every XX second.
display_cpu_level = 1 #cpu&mem info refresh times level, numbaer 1 is highest level, 1+ is lower level
display_netwk_level = 1 #network speed info refresh times level, numbaer 1 is highest level, 1+ is lower level
display_ip_level = 6 #ip address info refresh times level, numbaer 1 is highest level, 1+ is lower level
display_hdd_level = 7 #hdd info refresh times level, numbaer 1 is highest level, 1+ is lower level
display_date_level = 12 #date info refresh times level, numbaer 1 is highest level, 1+ is lower level
my_netwk_card = 'WLAN 3' #set network adapter name by user
bps = 115200 #serial speed value
timex = None
# ------------------------------ end ---------------------------------------------
<<<<<<<<<<<<<<<<<<<<<<<<项目工程>>>>>>>>>>>>>>>>>>
这里主要是放一下主函数,完整的可去项目工程链接去看
void main(void)
{
int i=0;
uint8_t sum_check;
uint8_t str[UART_RX_SIZE-3];
uint8_t upload_str[8]={0x04, 0x0E, 0x15, 0x04, 0x04, 0x04, 0x04, 0x00}; // char "↑"
uint8_t download_str[8]={0x04, 0x04, 0x04, 0x04,0x15, 0x0E, 0x04, 0x00}; //char "↓"
/*High speed internal clock prescaler: 1*/
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
/* EVAL COM (USARTx) configuration -----------------------------------------*/
/* USART configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Receive and transmit enabled
- USART Clock disabled
*/
STM_EVAL_COMInit(COM1, (uint32_t)115200, USART_WordLength_8b, USART_StopBits_1,
USART_Parity_No, (USART_Mode_TypeDef)(USART_Mode_Tx | USART_Mode_Rx));
/* Enable general interrupts */
enableInterrupts();
/* Enable USART */
USART_Cmd(EVAL_COM1, ENABLE);
lcd1602_init();
customer_word(upload_str, 0x40, 8); // upload_str set code 0x00
customer_word(download_str, 0x48, 8); // download_str set code 0x01
rx_size = UART_RX_SIZE;
/* Check if the MCU has resumed from IWDG reset */
if (RST_GetFlagStatus(RST_FLAG_IWDGF) != RESET)
{
/* Clear IWDG Flag */
RST_ClearFlag(RST_FLAG_IWDGF);
}
/* IWDG Configuration */
IWDG_Config();
while (1)
{
// Enable serial rx interrupt event
USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE);
//Check header and data length
// data format: header(1byte) + first line data(16byte) +
// Second line data (16byte)+ data lines(1byte) + sum number(1byte)
if(rxcount == UART_RX_SIZE && rxbuffer[0] == 0xff){
sum_check = 0;
for(i=1;i<(rxcount-1);i++){
sum_check += rxbuffer[i];
if(rxbuffer[i] == 0xff){
str[i-1] = 0x00; // upload_str code 0x00
}else if(rxbuffer[i] == 0xfe){
str[i-1] = 0x01; // download_str code 0x01
}else{
str[i-1] = rxbuffer[i];
}
}
if(sum_check == rxbuffer[UART_RX_SIZE-1]){ // check sum ok
sum_check = 1;
//show first line str.
show(0, 0, str, 16);
if(rxbuffer[UART_RX_SIZE-2] == 1){
//show second line str.
show(0, 1, &str[16], 16);
}
}else{ //check fail
sum_check = 0;
}
//reply result: 0 is fail, 1 is ok
uart_sent(&sum_check, 1);
//clear
rxcount = 0;
}
//set timer dog, keep system fine.
IWDG_ReloadCounter();
}
}
<<<<<<<<<<<<<<<<<<<<<<<<项目工程>>>>>>>>>>>>>>>>>>
python -m pip install --upgrade pip --force-reinstall
pip install --user -r requirements.txt
python get_cpu_resource.py