STM8S903K3基于ST Visual Develop开发串口接收中断示例

STM8S903K3基于ST Visual Develop开发串口接收中断示例


📗UART中断请求

在这里插入图片描述

  • 📓UART中断映射图
    在这里插入图片描述
  • 📑中断向量表有关串口中断号信息:
    在这里插入图片描述

串口相关寄存器

  • 状态寄存器(UARTx_SR)
    在这里插入图片描述
  • 数据寄存器(UART_DR)
    在这里插入图片描述

⛳注意事项

  • 设置波特率,必须注意以下几点:
    1. 必须先写BRR2
    1. BRR1存放的是分频系数的第11位到第4位,
    1. BRR2存放的是分频系数的第15位到第12位,和第3位到第0位

🌻接收中断数据转发功能实现

🔖将通过串口接收到的数据转发出去,对数据不做任何处理。

#include"stm8s903k3.h"

void CLK_Init(void)
{
	//  CLK_ECKR = 0x01; //开启外部时钟寄存器
//  CLK_SWR = 0xb4; //HSE外部时钟源作为主时钟源
//  CLK_CKDIVR = 0x00;//不分频
  
  CLK_ICKR |= 0X01; //使能内部高速时钟 HSI
  CLK_CKDIVR = 0x00; // 不分频,16M
 //    CLK_CKDIVR = 0x08; // 16M内部RC经2分频后系统时钟为8M 
   while(!(CLK_ICKR&0x02)); //HSI准备就绪
     CLK_SWR = 0xE1;//HSI内部时钟源作为主时钟源(复位值)
}
void UART1_Init(void)
{
    PD_DDR |= ( 1 << 5 );                       //输出模式 TXD
    PD_CR1 |= ( 1 << 5 );                       //推挽输出
    
    PD_DDR &= ~( 1 << 6 );                      //输入模式 RXD
    PD_CR1 &= ~( 1 << 6 );                      //浮空输入
    
	 UART1_CR3 = 0x00;
	 /*disable LIN mode 
	-one stop bit
	-disable SCK
	*/
    UART1_CR2  = 0x00;
		/*disable TX interrupt
	  disable TX completion interrupt
		disable RX interrupt
		disable idle interrupt
		disable TX and RX
		没有发送断开帧
	*/
    UART1_CR3  = 0x00;
		/*one start bit 
	eight data bits 
	 wake up by idle bus
	 disable ECC and EEC interrupt
	 UART enable
	*/
	
/* 波特率:9600 */  
   UART1_BRR2 = 0x02;//
   UART1_BRR1 = 0x68;//
  /* 波特率:115200 */   
//    UART1_BRR2 = 0x0b;
 //   UART1_BRR1 = 0x08;
 
	UART1_CR2  |= 0x20;
	UART1_CR2  |= 0x0C; //enable TX and RX

}

//char putchar(char c)
//{
 // 发送一个字符 c 到UART1
//	UART1_DR = c;
//等待发送完毕 */
// while (!(UART1_SR&0x40));
// return (c);
//}

void delay (unsigned int x)
{
	unsigned int i,j;
	for(i=x;i>0;i--)
		for(j=300;j>0;j--);
}


//阻塞式发送函数
void SendChar( unsigned char dat )
{
  /* 发送一个字符 c 到UART1 */
	UART1_DR = dat;
 /* 等待发送完毕 */
 while (!(UART1_SR&0x40));

}
//发送字符串
void SendString( unsigned char* s )
{
    while( '\0' != *s )
    {
        SendChar( *s );
        s++;
    }
}



//接收中断函数 中断号18
@far @interrupt void UART1_Handle( void )
{
	while(!(UART1_SR&0x40));
	RevByte  = UART1_DR ;
	 UART1_DR = RevByte ;//转发出去
	while(!(UART1_SR&0x40));
}

void main()
{	
	_asm("sim");    //disable all interrupt
		CLK_Init();
	UART1_Init();
	_asm("rim");    //enable all interrupt
	while(1);
}
  • 🌿中断向量表源文件:stm8_interrupt_vector.c
typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector {
	unsigned char interrupt_instruction;
	interrupt_handler_t interrupt_handler;
};

@far @interrupt void NonHandledInterrupt (void)
{
	/* in order to detect unexpected events during development, 
	   it is recommended to set a breakpoint on the following instruction
	*/
	return;
}

extern void _stext();     /* startup routine */
//extern @far @interrupt  void TIM1_OVR_UIF(void);
extern @far @interrupt void UART1_Handle(void);
struct interrupt_vector const _vectab[] = {
	{0x82, (interrupt_handler_t)_stext}, /* reset */
	{0x82, NonHandledInterrupt}, /* trap  */
	{0x82, NonHandledInterrupt}, /* irq0  */
	{0x82, NonHandledInterrupt}, /* irq1  */
	{0x82, NonHandledInterrupt}, /* irq2  */
	{0x82, NonHandledInterrupt}, /* irq3  */
	{0x82, NonHandledInterrupt}, /* irq4  */
	{0x82, NonHandledInterrupt}, /* irq5  */
	{0x82, NonHandledInterrupt}, /* irq6  */
	{0x82, NonHandledInterrupt}, /* irq7  */
	{0x82, NonHandledInterrupt}, /* irq8  */
	{0x82, NonHandledInterrupt}, /* irq9  */
	{0x82, NonHandledInterrupt}, /* irq10 */
	{0x82, NonHandledInterrupt}, /* irq11 TIM1*/
	{0x82, NonHandledInterrupt}, /* irq12 */
	{0x82, NonHandledInterrupt}, /* irq13 */
	{0x82, NonHandledInterrupt}, /* irq14 */
	{0x82, NonHandledInterrupt}, /* irq15 */
	{0x82, NonHandledInterrupt}, /* irq16 */
	{0x82, NonHandledInterrupt}, /* irq17 */
	{0x82, UART1_Handle}, /* irq18 */
	{0x82, NonHandledInterrupt}, /* irq19 */
	{0x82, NonHandledInterrupt}, /* irq20 */
	{0x82, NonHandledInterrupt}, /* irq21 */
	{0x82, NonHandledInterrupt}, /* irq22 */
	{0x82, NonHandledInterrupt}, /* irq23 */
	{0x82, NonHandledInterrupt}, /* irq24 */
	{0x82, NonHandledInterrupt}, /* irq25 */
	{0x82, NonHandledInterrupt}, /* irq26 */
	{0x82, NonHandledInterrupt}, /* irq27 */
	{0x82, NonHandledInterrupt}, /* irq28 */
	{0x82, NonHandledInterrupt}, /* irq29 */
};

🌼通过自定义传输协议,选择性处理接收数据

🚩此方法可以有针对性的对接收数据进行筛选。

📝示例代码

⛳通过对带有结束符且带换行符来判断数据接收完成,不过这样有一定的局限性。如果想实现对不定长数据完整接收需要添加更多的条件判断才行。

#include"stm8s903k3.h"
#include "string.h"
unsigned char cnt=0;
 unsigned char RxBuffer[32];
unsigned char flag=0;

void CLK_Init(void)
{
	//  CLK_ECKR = 0x01; //开启外部时钟寄存器
//  CLK_SWR = 0xb4; //HSE外部时钟源作为主时钟源
//  CLK_CKDIVR = 0x00;//不分频
  
  CLK_ICKR |= 0X01; //使能内部高速时钟 HSI
  CLK_CKDIVR = 0x00; // 不分频,16M
 //    CLK_CKDIVR = 0x08; // 16M内部RC经2分频后系统时钟为8M 
   while(!(CLK_ICKR&0x02)); //HSI准备就绪
     CLK_SWR = 0xE1;//HSI内部时钟源作为主时钟源(复位值)
}
void UART1_Init(void)
{
	PD_DDR |= ( 1 << 5 );                       //输出模式 TXD
    PD_CR1 |= ( 1 << 5 );                       //推挽输出
    
    PD_DDR &= ~( 1 << 6 );                      //输入模式 RXD
    PD_CR1 &= ~( 1 << 6 );                      //浮空输入
	 UART1_CR3 = 0x00;
	 /*disable LIN mode 
	-one stop bit
	-disable SCK
	*/
    UART1_CR2  = 0x00;
		/*disable TX interrupt
	  disable TX completion interrupt
		disable RX interrupt
		disable idle interrupt
		disable TX and RX
		没有发送断开帧
	*/
    UART1_CR3  = 0x00;
		/*one start bit 
	eight data bits 
	 wake up by idle bus
	 disable ECC and EEC interrupt
	 UART enable
	*/
	
/* 波特率:9600 */  
   UART1_BRR2 = 0x02;//
   UART1_BRR1 = 0x68;//
  /* 波特率:115200 */   
//    UART1_BRR2 = 0x0b;
 //   UART1_BRR1 = 0x08;
 
 	UART1_CR2  |= 0x20;
	UART1_CR2  |= 0x0C; //enable TX and RX
 


}

//char putchar(char c)
//{
 // 发送一个字符 c 到UART1
//	UART1_DR = c;
//等待发送完毕 */
// while (!(UART1_SR&0x40));
// return (c);
//}

void delay (unsigned int x)
{
	unsigned int i,j;
	for(i=x;i>0;i--)
		for(j=300;j>0;j--);
}


//阻塞式发送函数
void SendChar( unsigned char dat )
{
  /* 发送一个字符 c 到UART1 */
	UART1_DR = dat;
 /* 等待发送完毕 */
 while (!(UART1_SR&0x40));

}
//发送字符串
void SendString( unsigned char* s )
{
    while( '\0' != *s )
    {
        SendChar( *s );
        s++;
    }
}

//接收中断函数 中断号18
@far @interrupt void UART1_Handle( void )
{

    char dataTmp ;
    UART1_SR &= ~( 1 << 5 ); //RXNE 清零
		 dataTmp = UART1_DR;
		if((0x0d != dataTmp)&&(0x0a != dataTmp))//换行符和回车符判断结束
		{
			RxBuffer[cnt++] = dataTmp;		
	  }
	  else
	{
		RxBuffer[cnt] = '\0';
		cnt=0;
		flag = 1;
	
		
	}

}

void main()
{	
	_asm("sim");    //disable all interrupt
	CLK_Init();
	UART1_Init();
	_asm("rim");    //enable all interrupt
	while(1)
	{
	if(flag == 1)
	{
		SendString(RxBuffer);
		SendChar('\n');
		memset(RxBuffer,0,sizeof(RxBuffer));
		flag =0;		
	}
  }
}

中断向量表源文件中的代码和上面的示例是相同的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值