STM8S UART串口使用中断收发数据

2019-09-17来源: eefocus关键字:STM8S  UART  串口使用  中断  收发数据

原来调过STM8L的串口,逻辑简单,中断清晰,换成STM8S105K4后,虽然也是用STD库,除去函数名、宏名等语言层面的差异以外,中断处理方面也有些不一样的地方,特此记之。

和此篇【STM8L USART串口使用】结构相同,也是中断异步模式,但为调用方便起见,在调用层面改为同步。

(STM8S105K的MCU下,RX为PD6,RX为PD5。)


使用方面,感觉主要困扰就是中断名、使用场合和时机不明确、不清晰,这一点不如STM8L的定义清晰。

举例而言,开关中断用UART2_IT_RXNE_OR,清中断则用UART2_IT_RXNE。不能开关时用UART2_IT_RXNE,也不能清中断时用UART2_IT_RXNE_OR,否则STD库中参数合法assert断言,分分钟让程序挂起。

供大家参考。


以下是示例代码,为了和应用层更好的分离和代码通用化,设置了独立的UART的读写缓冲区,如果缓冲较大的情况下,请用@near置于分离数据区初始化。

另外虽然是中断驱动,考虑到绝大多数使用场景是同步的,设置了同步状态变量,读写函数中检测。改成中断的只需将状态变量的判断改成在应用面判断即可。


1. 读写缓冲和标识值定义


#define UART_BUF_SIZE 128


/* Read buffer */

uint8_t read_ok = 0; // 读完成flag

uint8_t read_idx = 0;

uint8_t read_len = 0;

@near uint8_t read_buffer[UART_BUF_SIZE]; // 缓冲区设置较大的时候可用@near放置


/* Write buffer */

uint8_t writ_ok = 0; // 写完成flag

uint8_t writ_idx = 0;

uint8_t writ_len = 0;

@near uint8_t writ_buffer[UART_BUF_SIZE];  // 缓冲区设置较大的时候可用@near放置


2. 串口初始化

STM8S105K4只有一个串口,即UART2


int8_t uart_init(void)

{

// 串口参数请按需求修改

UART2_DeInit();

UART2_Init((uint32_t)38400, 

UART2_WORDLENGTH_8D, 

UART2_STOPBITS_1, 

UART2_PARITY_NO, 

UART2_SYNCMODE_CLOCK_DISABLE, 

UART2_MODE_TXRX_ENABLE);

// 显式关中断(默认就是关)

// 注意:

// 读中断名字是UART2_IT_RXNE_OR,而不是UART2_IT_RXNE

// 写中断名字为UART2_IT_TXE

UART2_ITConfig(UART2_IT_RXNE_OR, DISABLE);

UART2_ITConfig(UART2_IT_TXE, DISABLE);

//串口使能

UART2_Cmd(ENABLE);

return 0;

}


3. 读写函数


// 写多个字节

void uart_send_n_byte(uint8_t* data, uint8_t len)

{

uint16_t count = 0;

UART2_ITConfig(UART2_IT_TXE, DISABLE);


// 准备写数据缓冲(从用户数据区复制到串口写缓冲、初始化索引值等)

memcpy(writ_buffer, data, len);

writ_idx = 0;

writ_len = len;


// 开写中断

UART2_ITConfig(UART2_IT_TXE, ENABLE);

while(!writ_ok) {  // 等待写完成(同步处理)

count++;

if( count >= 10000 ) {  // 简单的超时处理,不需要超时可以去除

writ_idx = 0;

writ_len = 0;

break;

}

}

writ_ok = 0;  // 写完成、重置写完成flag

return;

}


// 读多个字节

void  uart_read_n_byte(uint8_t* data, uint8_t len)

{

// 关读中断

UART2_ITConfig(UART2_IT_RXNE_OR, DISABLE);


// 清空读缓冲(重置读索引值即可)

read_idx = 0;

read_len = len;


// 开读中断

UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);

while(!read_ok); // 等待读操作完成(同步化处理)、添加超时处理可参照上述写操作

read_ok = 0;     // 写完成、重置写完成flag

memcpy(data, read_buffer, read_len);  // 复制数据到用户缓冲区

return;

}


4. 中断处理


INTERRUPT_HANDLER(UART2_TX_IRQHandler, 20)

{

// 写操作自动清中断,因此可以不用显式清中断

//UART2_ClearITPendingBit(UART2_IT_TXE); 

// 从写缓冲中写出1字节

UART2_SendData8(writ_buffer[writ_idx++]);


// 全部写完、关写中断、置写完成标志(同步化处理)

if( writ_idx == writ_len ) {

UART2_ITConfig(UART2_IT_TXE, DISABLE);

writ_ok = 1;

}

}


 INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21)

{

// 读操作自动清中断,因此可以不用显式清中断

// 注意这里的中断名是RXNE,不是RXNE_OR

UART2_ClearITPendingBit(UART2_IT_RXNE);


// 读1字节

read_buffer[read_idx++] = UART2_ReceiveData8();


// 全部读完,关中断(UART2_IT_RXNE_OR),置读完成标志(同步化处理)

if( read_idx == read_len ) {

UART2_ITConfig(UART2_IT_RXNE_OR, DISABLE);

read_ok = 1;

}

}


5. 使用代码例


// 写2字节

uint8_t buf[32];

memset(buf, 0x00, sizeof(buf));

buf[0] = 0xCC;

buf[1] = 0xDD;

uart_send_n_byte(buf, 2);


// 简单读(必须读满24字节才返回)

memset(buf, 0x00, sizeof(buf));

uart_send_n_byte(buf, 24);

关键字:STM8S  UART  串口使用  中断  收发数据 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic474716.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm8s中UART的用法(四种UART中断)
下一篇:UART0串口编程(三):中断方式的串口编程;用中断编写发送

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

ST系列STM8S003F3P6单片机芯片介绍
众所周知,意法半导体的stm8s系列主流8位微控制器适于工业、消费类和计算机市场的多种应用,特别是要实现大批量的情况。基于STM8专有内核,STM8S系列采用ST的130纳米工艺技术和先进内核架构,主频达到24 MHz,处理能力高达20MIPS。嵌入式EEPROM、RC振荡器和全套标准外设为设计者提供了稳定且可靠的解决方案。相关工具链,从经济型探索套件到更复杂的评估套件和第三方工具,为利用STM8S微控制器进行开发提供了极大方便。STM8S系列包括四个产品线,具有不同特性,但是保持了全面兼容性和可升级性,从而减少了未来产品设计变更。•STM8S003/005/007超值型是入门级产品,具有基本功能。•STM8S103/105基本型
发表于 2020-07-21
<font color='red'>ST</font>系列<font color='red'>STM8S</font>003F3P6单片机芯片介绍
STM8S如何实现Atomthreads最低功耗
(status);  }针对STM8我们最自然想到的是在其中加一个wfi,STM8进入wfi模式几乎不会影响任何外设的运行。以STM8S105K4为例,其进入该模式的典型电流是1.8mA。这个电流,用一节2000mA手机供电,理论上也最多能坚持46天,才一个月多点。这个记录太差了。STM8还有一个HALT模式,这是该芯片的最低功耗模式,电流是uA级别。但是该模式有诸多限制,进入该模式系统几乎所有的clock都停止,你的TImer,adc,uart等等全部停止,除了AWU。atomthreads如果你在idle直接进入HALT,因为基本只有外部中断可以唤醒退出这个模式,当系统醒来了,请你想想,你的系统心跳还准么?你的应用线程
发表于 2020-07-21
<font color='red'>STM8S</font>如何实现Atomthreads最低功耗
三分钟看懂stm8s单片机实现多通道转换
今天在使用stm8s单片机的AD功能,单片机上有AN0到AN9十个通道。想只用其中的三路AN5到AN7。//ADC初始化void ADC_Init(void){ADC_CR1 = 0x50;ADC_CR2 = 0x38;ADC_TDRL = 0xE0;//禁止施密特触发}unsigned int Read_ADC_Temp(unsigned channel){unsigned int i,ADtemp;ADC_Init();//ADC_CSR = 0x00;ADC_CSR = channel;ADC_CR1 = 0x01;// CR1寄存器的最低位置1,使能ADC转换for(i = 0;i 《 300;i
发表于 2020-07-21
三分钟看懂<font color='red'>stm8s</font>单片机实现多通道转换
STM8S的定时器周期中断时钟测试系统
  1 问题  在下面的测试程序中,如果将Init_CLK()函数中的 CLK_CKDIVR |= 0x08;去掉’|‘,则TIM1的功能实现跟预设定相同(10ms中断一次),但是TIM2的PWM频率就变高了;如果加上,则TIM2的功能实现跟预设定相同(产生1Hz的PWM),但是TIM1的周期就变长了;  尝试了很多测试,均无效(买的开发板和另一块gs自画板测试也都一样)。  2 尝试  因为STM8S默认使用内部16M高速RC振荡器,且8分频,则系统启动主时钟为2M。即CLK_CKDIVR = 0X18;,如果再去赋值CLK_CKDIVR |= 0X08; 则主时钟还是不变即0X18,但是如果赋值为CLK_CKDIVR
发表于 2020-07-21
<font color='red'>STM8S</font>的定时器周期中断时钟测试系统
STM8S利用STVP方式进行IO复用分析
1 说明STM8S的IO复用用程序代码配置起来比较麻烦,一般是操作flash来操作opTIon byte字节,配置寄存器更加麻烦,可以使用STM 标准外设驱动库来设置。本文使用一种界面配置的方式来配置IO复用管脚,即使用STVP来配置。 因为FLASH保存的数据是掉电不丢失的,先用STVP把OpTIon Bytes擦写好后,再用STVD仿真器烧写程序就可实现IO复用了。程序方式配置IO复用见这里2 配置流程【step1】打开STVP软件【step2】打开我们需要下载的xxx.s19文件,CTRL+F5(File-》Ram Exec)【step3】配置需要复用的引脚IO口的复用功能主要配置在于AFR0-AFR7。这里我们配置定时器
发表于 2020-07-21
<font color='red'>STM8S</font>利用<font color='red'>ST</font>VP方式进行IO复用分析
采用STM8S内部时钟产生PWM(TIM2)
  1 说明  采用STM8S内部时钟(HSI);  PWM模式2;  占空比为50%,频率为2Hz(方便测试LED灯);  PD2口外接LED灯,PD2口输出PWM波;  系统时钟初始化很重要:CLK_CKDIVR |= 0x08;  2 代码
发表于 2020-07-14
采用<font color='red'>STM8S</font>内部时钟产生PWM(TIM2)
小广播
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved