【STM8】串口通信实现(LED的亮灭控制)

情景说明:
找到一块STM8开发板,打算拿着做点小东西玩一下。实现LED亮灭控制

1.开发平台及环境

芯片型号:STM8S03F
开发板图片:
在这里插入图片描述
开发环境:
使用IAR软件。环境搭建,请自行百度。
在这里插入图片描述

2.波特率配置

公式:

公式
其中:

  • f为时钟源频率
    主时钟经过CLK_CKD IVR分频得来。我这里使用HSI内部时钟16M,CLK_CKDIVR=00不分频,即f=16M。
  • UATRT_DVI 串口分频。
    也就是我们要计算的数值
    以115200举例:UATRT_DVI = 16m/115200 = 138.89。十六进制结果约为:0x008B
计算寄存器的值

UATRT_DVI[15:0] 由BRR2和BRR1组成。
BRR1[7:0]对应UATRT_DVI [11:4]
BRR2[3:0]对应UATRT_DVI [3:0]
BRR2[7:4]对应UATRT_DVI [15:12]
所以,0x008B中间的给BRR1,俩边给BRR2。如下图。
在这里插入图片描述

注意:
1.BRR1 = 0x00表示禁用,所以给BRR1的值应该大于0.
2.先给BRR1赋值,然后给BRR2赋值
3.注意误差。误差会影响数据有效性。

3.控制寄存器配置

寄存器功能表
在这里插入图片描述

  • TIEN:开始发送中断使能(一般不用)
  • TCIEN:发送完成中断使能
  • RIEN:接收中断使能
  • ILIEN:IDLE中断使能
  • TEN:发送使能
  • REN:接收使能
  • RWU:接收唤醒
  • SBK:发送断开帧。

开启发送和接收功能,启用接收中断配置如下

    UART1_CR2=0x00;// 先清0
    
    UART1_CR2_TEN = 1;     //允许发送
    UART1_CR2_REN = 1;     //允许接收
    UART1_CR2_RIEN = 1;    //接收中断使能

上述代码也可写成:UART1_CR2=0x00;// 0010 1100

4.关键代码

时钟初始化

这里使用内部时钟,16M

#define SYS_CLOCK 16
void CLOCK_Config(unsigned char SYS_CLK)
{
    
    
   //时钟配置为内部RC,16M
   CLK_CKDIVR &=0xe7;
  
   switch(SYS_CLK)
   {
    
    
      case 2: CLK_CKDIVR|=((1<<4)|(1<<3)); break;
      case 4: CLK_CKDIVR|=(1<<4); break;
      case 8: CLK_CKDIVR|=(1<<3); break;
   }
}
串口初始化:

波特率115200

void  UART1_init(void)
{
    
    
    UART1_CR1=0x00;
    UART1_CR2=0x00;
    UART1_CR3=0x00;
    UART1_BRR2 = 0x0B;     //  16m/9600 = 1666.67(0x0683有误差 ) 取中间和俩边   BRR2 = 0x03,BRR1=0x68
    UART1_BRR1 = 0x08;     //115200波特率
    UART1_CR2_TEN = 1;     //允许发送
    UART1_CR2_REN = 1;     //允许接收
    UART1_CR2_RIEN = 1;    //接收中断使能
}
发送一个字节:
void  UART1_SendByte(unsigned char dat)
{
    
    
  	UART1_SR &= 0xBF; // 清除清除发送完成TC标志位
	UART1_DR = dat;
	while((UART1_SR & 0x40)==0x00); // SR状态寄存器,第6位为0表示完成 
	UART1_SR &= 0xBF; // 清除清除发送完成TC标志位
}

接收中断

实现接收到1,开LED1
接收到2,开启LED2
其他关闭LED。

#pragma   vector = UART1_R_RXNE_vector   //接受中断向量

//接受中断函数
__interrupt void UART1_RX_IRQHandler(void)
  {
    
    
    unsigned char rx_data;
    
    if(UART1_SR & 0x20) // 是否接收完成
    {
    
    
	     UART1_SR_RXNE = 0;// 清除接收标识
         rx_data = UART1_DR; // 读取数据
         
         // 用户处理
         if(rx_data == '1')
         {
    
    
           LED1_ON();
           LED2_OFF();
         }
         else if(rx_data == '2')
         {
    
    
           LED2_ON();
           LED1_OFF();
         }
         else
         {
    
    
           LED1_OFF();
           LED2_OFF();
         }
    }
        
  }
主函数
void main(  )
{
    
    

  asm("sim");//全局中断
  CLOCK_Config(SYS_CLOCK);
  UART1_init();   
  timer_Init();
  LED_init();
 asm("rim");//开全局中断 
 
  while(1);     
   
}

猜你喜欢

转载自blog.csdn.net/qq_44078824/article/details/123689074