在STM32上创建链表并实现LCD滚动显示串口消息

发布者:牟牟的侬最新更新时间:2019-05-11 来源: eefocus关键字:STM32  创建链表  LCD  滚动显示  串口消息 手机看文章 扫描二维码
随时随地手机看文章

在实现STM32开发ESP8266的时候发现ESP8266串口发送的消息行数很多, 如果使用普通的数组来存储消息需要大量的存储开销, 并且数据的显示也会损耗MCU的处理速度, 故而实现对消息的传输装入一个可以动态拓展, 并且具有灵活的调用形式的容器. 链表理所当然成为首选.


关于C语言链表的相关操作本文不再详细叙述, 若有需求请移步网址:https://blog.csdn.net/morixinguan/article/details/68951912先学习链表后再来学习在STM32创建链表.


首先粘贴STM32上链表.c文件的代码:


//////roll_display.c的代码

 

#include "roll_display.h"

#include

#include

 

 

 

Linkedlist *creat_list(int size)       //创建链表

{

int i;

Linkedlist *head = (Linkedlist *)malloc(sizeof(Linkedlist));

Linkedlist *temp = head;

head->Data[0] = 0;

for (i=0;i {

Linkedlist *node = (Linkedlist *)malloc(sizeof(Linkedlist));  //节点

node->next = NULL;    //确保下一次迭代时为空

temp->next = node;    //指向下一个节点

temp = node;          //迭代

}

return head;

}

 

Linkedlist *add_last_node(Linkedlist *head)

Linkedlist *node = (Linkedlist *)malloc(sizeof(Linkedlist));   //创建新的节点

Linkedlist *temp = head;

node->next = NULL;

while (temp->next != NULL)

temp = temp->next;

temp->next = node;

return head;

}

 

Linkedlist *reduce_first_node(Linkedlist *head)   //去除链头

{

Linkedlist *new_head = (Linkedlist *)malloc(sizeof(Linkedlist));

new_head = head->next;      //新链头指向下一个节点

free(head);                 //释放原本的旧链头

return new_head;

}

 


接着是.h文件的代码:


//////////roll_display.h文件的代码

 

#ifndef _ROLL_DISPLAY_H

#define _ROLL_DISPLAY_H

#include

#include

 

struct List         //节点

{

unsigned char Data[100];

struct List *next;

};

 

typedef struct List Linkedlist;

 

Linkedlist *creat_list(int size);

Linkedlist *add_last_node(Linkedlist *head);   //嵌入节点

Linkedlist *reduce_first_node(Linkedlist *head);   //替代第一个节点

 

 

 

#endif

然后在主函数中调用代码时发现 编译会报错, 错误信息为//__use_no_semihosting was requested, but _ttywrch was 


大概意思为 编译需要使用半主机模式, 原因是因为malloc函数和free函数在MCU上有些不适用, 需要进行重定义 ttywrch函数


其实重定义函数在学习usart串口通信时已经使用过, 当时重定义的是printf函数使用的fputs函数


那么本次创建链表需要重定义ttywrch函数,具体代码为在代码任意处使用定义:

 


_ttywrch(int ch)        //为了避免malloc的定义错误  半主机模式

{  

}

 


这样就将ttywrch函数定义为一个无用函数, 编译就没有错误啦.


但是! 在之后使用链表时, 比如将创建的链表中Data数组的数据在串口中打印出来时发现打印的消息和想象中完全不符合!


之后经过我大量的检查后得出结论, 可能调用函数创建链表的栈堆不够使用造成的! 然后我打开STM32的启动文件, 也就是    

图中的startup_stm32f40_41xxx.c, 将其中的Heap_Size

改成了0x00002000 , 这样就是链表可使用的栈堆加大, 再次使用时就发现, 链表已经可以使用了!


至此STM32上链表的创建已经完成!


 


最后讲一下LCD上滚动显示串口消息的思路,:

创建一个具有10个节点的链表, 每次将新接收到的消息放在一个新的节点中, 并将其添加到链表的最后, 之后删除头节点, 成为一个新的链表, 对应LCD顺序显示每一个节点的消息, 并实现迭代.


代码如下:


#include "sys.h"

#include "usart.h"

#include "lcd.h"

#include "string.h"

#include "roll_display.h"

 

//__use_no_semihosting was requested, but _ttywrch was 

_ttywrch(int ch)        //为了避免malloc的定义错误  半主机模式

{  

}

 

u8 len,i,n;

u8 line=50;     //line 第几行

 

int main(void)

{

Linkedlist *head = creat_list(9);   //创建链表

Linkedlist *temp = head;

Linkedlist *new_temp = head;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

delay_init(168);      

uart_init(115200);

LED_Init();  

  LCD_Init();           

POINT_COLOR=RED;     

LCD_ShowString(50,10,210,24,16,"Data:");

while(1)

{

if (USART_RX_STA&0x8000)

{

Linkedlist *new_head = (Linkedlist *)malloc(sizeof(Linkedlist));   //迭代时生成新链作为"抛弃链"

new_head = new_temp;

add_last_node(new_head);         //在链表最后添加一个节点

new_temp = reduce_first_node(new_head); ////去掉链表第一个节点  保存新链头并释放老链头

temp = new_temp;

len = USART_RX_STA&0x3FFF;

LCD_Fill(20,line,240,246,WHITE);       //对动态显示行清除显示

for (i=0;temp->next != NULL;i++)

{

LCD_ShowString(20,line,240,12,16,temp->Data);    //每次对下一行显示

temp = temp->next;

line += 20;   

for (n=0;n temp->Data[n] = USART_RX_BUF[n];   //最后一行写入数据

LCD_ShowString(20,line,240,12,16,temp->Data);    //链表最后一行显示

line=50;                             //底行

USART_RX_STA=0;

memset(USART_RX_BUF,0,len);          //清除接收缓存

}

}

}


关键字:STM32  创建链表  LCD  滚动显示  串口消息 引用地址:在STM32上创建链表并实现LCD滚动显示串口消息

上一篇:STM32的PWM的频率和占空比设定
下一篇:对于STM32F4库函数中GPIO_PinAFConfig()函数的解读

推荐阅读最新更新时间:2024-11-13 09:15

STM32】光敏传感器示例
01. 光敏传感器简介 光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、光纤式光电传感器、色彩传感器、CCD 和 CMOS 图像传感器等。光传感器是目前产量最多、应用最广的传感器之一,它在自动控制和非电量电测技术中占有非常重要的地位。 光敏传感器是利用光敏元件将光信号转换为电信号的传感器,它的敏感波长在可见光波长附近,包括红外线波长和紫外线波长。光传感器不只局限于对光的探测,它还可以作为探测元件组成其他传感器,对许多非电量进行检测,只要将这些非电量转换为光信号的变化即可。 探索者 STM32F4 开发板板载了一个光敏二极管(光敏电阻),
[单片机]
你ADC采集的数据都准确吗?
1写在前面 ADC:Analog Digital Converter,指模数转换,也就是(电压)模拟量转换成数字量。 大多数MCU中都集成了ADC模块,同时ADC也是在产品开发中使用率较高的一个模块,相信大部分人都使用过ADC这个功能。 在STM32中内置最多四个高级12位ADC控制器(ADC1、2、3、4)。当然,ADC控制器数量多少取决于STM32型号,还有部分STM32具有16位采样的ADC(如STM32F373)。他们提供自校准功能,用于提高环境条件变化时的ADC精度。 我们平时在使用ADC中要求不是很高,可能就没有在于ADC转换的值是否精确。但是,有些特定场合就需要更精确的转换值,那么我们就需要对ADC做更
[单片机]
你ADC采集的数据都准确吗?
STM32与GD32横向对比区别
GD32 是国产单片机,据说开发人员来自ST公司,GD32 也是以 STM32 作为模板做出来的。所以 GD32 和 STM32 有很多地方都是一样的,不过 GD32 毕竟是不同的产品,不可能所有东西都沿用 STM32,有些自主开发的东西还是有区别的。不同的地方如下: 1、内核 GD32 采用二代的 M3 内核,STM32 主要采用一代 M3 内核, ARM 公司的 M3 内核勘误,GD 使用的内核只有 752419 这一个 BUG。 2、主频 使用HSE(高速外部时钟):GD32的主频最大108M,STM32的主频最大72M 使用HSI(高速内部时钟):GD32的主频最大108M,STM32的主频最大64M 主频大意味着单片
[单片机]
<font color='red'>STM32</font>与GD32横向对比区别
基于STM32步进电机多细分控制的设计
本文主要介绍了一种基于STM32的混合式步进电机控制方案,STM32产生PWM(脉宽调制信号),利用PWM完成DAC转换,通过PWMDAC的输出电压实现对步进电机的多细分控制。该设计相比利用DAC数模转换芯片的设计方案具有电路简单,费效比高的优点,而且可实现步进电机十六分之一步的驱动控制,精度较高。 1、硬件设计 硬件设计框图如图1所示,主要由PC上位机给STM32F103发送控制命令,通过STM32F103控制A3988,从而驱动两个步进电机转动。其中,STM32F103是意法半导体公司生产的基于ARMCortex—M3内核的微控制器,内核架构先进,性能优越,主频可达72MHz,执行效率高,具有较高的运算能力及数据处理功能,
[单片机]
基于<font color='red'>STM32</font>步进电机多细分控制的设计
STM32 外部中断简介
STM32 IO 口中断的一些基础概念。STM32 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19 个外部中断为: 线 0~15:对应外部 IO 口的输入中断。 线 16:连接到 PVD 输出。 线 17:连接到 RTC 闹钟事件。 线 18:连接到 USB 唤醒事件。 在库函数中,配置 GPIO 与中断线的映射关系的函数 GPIO_EXTILineConfig()来实现的: void GPIO_EXTILineConfig(uint8_t
[单片机]
意法半导体新演示板帮助先进工业和消费电子厂商加快双电机设计
高集成度电机控制器STSPIN32G4依托STM32生态系统加快产品开发周期 2024年5月31日,中国- 意法半导体的EVSPIN32G4-DUAL演示板只用一个高集成度电机驱动器STSPIN32G4就能控制两台电机运转,加快产品开发周期,简化PCB电路板设计,降低物料成本。 EVSPIN32G4-DUAL电路板可以缩短机器人、多轴工厂自动化系统、园林设备、电动工具等先进工业设备和消费产品的研发周期,缩短产品上市时间 。STSPIN32G4电机控制器内置的Arm®Cortex®-M4微控制器(MCU)能够同时控制两个电机,实时执行矢量控制(FOC)等复杂算法。此外,MCU外设还支持有传感器或无传感器的FOC算法,
[工业控制]
意法半导体新演示板帮助先进工业和消费电子厂商加快双电机设计
基于STM32的0.96寸OLED时钟程序
用的是stm32自带的RTC时钟。硬件连接很简单,当然程序也是比较简单的,只写了温度(DS18B20),stm32自带RTC和OLED显示,大家可自行删改功能。 硬件连接: SDA --》PB13 SCL --》PB12 DS18B20----》PA15 OLED和DS18B20直接5V供电就成,效果如下: 单片机源程序如下: #include sys.h #include usart.h #include delay.h #include led.h #include key.h #include oled.h #include beep.h #include rtc.h #include ds18b20
[单片机]
基于<font color='red'>STM32</font>的0.96寸OLED时钟程序
编译可加载lcd驱动的linux uImage
pc:Centos5.4 内核:linux 3.0.1 开发板:ok6410 交叉编译器:arm-linux-gcc 4.4.1 LCD驱动程序 怎么写LCD驱动程序? 1. 分配一个fb_info结构体: framebuffer_alloc 2. 设置 3. 注册: register_framebuffer 4. 硬件相关的操作 测试: 1. make menuconfig去掉原来的驱动程序 - Device Drivers - Graphics support M S3C LCD framebuffer support 2. make uImage 出现错误:修改/drivers/media/video/samsung/t
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved