历史上的今天
返回首页

历史上的今天

今天是:2024年09月17日(星期二)

2019年09月17日 | STM8S UART串口使用中断收发数据

2019-09-17 来源:eefocus

原来调过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);

推荐阅读

史海拾趣

ETERNA公司的发展小趣事

2014年,ETERNA成为了ATP世界网球巡回赛瑞士公开赛的指定合作伙伴。这一合作标志着ETERNA在品牌建设和市场推广方面取得了新的突破。通过与ATP的合作,ETERNA不仅成功地将品牌与高端体育赛事相结合,还进一步提升了品牌形象和知名度。同时,ETERNA还为赛事提供了精准的计时服务,展现了其在电子技术领域的实力。

Freeport Resources Enterprises Corp公司的发展小趣事

为了应对矿业市场的周期性波动和不确定性风险,Freeport Resources实施了多元化经营战略。在保持矿业勘探和开发核心业务的同时,公司还涉足了电子材料贸易、新能源开发等多个领域。通过多元化经营,Freeport Resources有效分散了经营风险,提高了整体抗风险能力。此外,多元化经营还为公司带来了新的增长点,促进了公司的持续健康发展。

GTE Microcircuits公司的发展小趣事
复合放大器在长时间工作后性能下降的原因可能包括元件老化(如电阻、电容值的变化)、温度漂移、以及电源波动等。为了缓解这些问题,可以定期校准电路、使用温度稳定性好的元件、以及加强电源的稳定性和滤波。
Applied Engineering Products (AEP)公司的发展小趣事

随着公司规模的扩大和产品种类的增多,AEP公司意识到质量管理的重要性。公司引进了一套先进的质量管理体系,从原材料采购、生产过程到产品出厂,每一个环节都进行严格的质量控制。同时,公司还加强了对员工的培训和管理,确保每一名员工都能严格按照质量标准进行操作。这一举措大大提高了AEP公司的产品质量和客户满意度,为公司的长期发展奠定了坚实基础。

诚润电子(CHEVRON)公司的发展小趣事

诚润电子(CHEVRON)自创立之初,就以技术为核心竞争力。公司在2010年正式成立,由一群热衷于电子保护元件研发的工程师创立。他们深知,在这个日新月异的电子行业中,只有不断创新,才能在竞争中立于不败之地。因此,诚润电子从一开始就专注于电子保护元件的研发和生产,通过不断的技术创新,逐渐在市场中树立起了自己的品牌。

Anritsu公司的发展小趣事

诚润电子深知,一个优秀的团队是企业成功的关键。因此,他们一直致力于打造一支高素质、专业化的团队。公司注重员工的培训和发展,为员工提供广阔的职业发展空间和良好的福利待遇。同时,诚润电子还积极营造一种积极向上的企业文化氛围,让员工在工作中感受到归属感和成就感。这种良好的团队建设机制为诚润电子的持续发展提供了有力的保障。

问答坊 | AI 解惑

51单片机程序-word-1

最新的51单片机程序-word版本…

查看全部问答>

老师,帮我看看设计程序(程序后半部分)

(老师,这个程序是程序显示70h到74h中数值的程序,紧接前面发给你的那个程序。) ;显示70H到74H中的数值 MOV R0,#70H ;显示70H中的数值 LOOP1: MOV A,@R0 MOV DPTR,#LEDCODE MOVC A,@A+DPTR MOV R2,#8 LOOP0: RRC A ...…

查看全部问答>

线性相位

本帖最后由 paulhyde 于 2014-9-15 09:33 编辑 线性相位  …

查看全部问答>

恭喜专区盛大开通

欢迎大家踊跃发帖、讨论!…

查看全部问答>

c51单片机

我刚学51单片机不久,最近遇到一个难题,我的板子上控制LED和数码管的都是P2口,请教高手,用什么办法可以同时按照自己的想法控制两者,做到互不影响?(希望能说的明白点) -- 给20点数,不要嫌少啊,是我目前全部的点数了。…

查看全部问答>

VS 2005 下WIN CE 6模拟器 语言选择中文 显示乱码

我先定制英文的CE,模拟可以显示正确。然后选择了语言中文,再试就是一些方框了,看不到中文。请问为什么呢?…

查看全部问答>

EVC3.0+ppc2002安装问题!

安装很正常,但建立一个Project后,Build时提示Connect,这时系统启动PPC2003,但一会出现Timeout:fail connect to device. 请问各位高手,如何让我的调试环境正常运行。…

查看全部问答>

关于网络的问题。

有问题请教: 自己做了板子,芯片是107vc,电脑跟板子之间通过一个5口的交换机连接,ping板子时返回时间都少于1ms; 但是公司的网络接进这个5**换机以后,ping板子返回的时间就变得很不稳定,而且大部分都在几百毫秒以上,有时甚至超过一千毫 ...…

查看全部问答>

如何判断串口发送给单片机的数据是相同的呢?

问一个问题 假如我在串口调试助手上发送数据:pass word 如果单片机收到这组数据后,进入一个条件, 这里怎么样判断单片机收到这个数据呢? 怎么比较出发出来的数据就是pass word呢? 是不是要"p","a","s","s","w","o ...…

查看全部问答>