STM32
直播中

王平

7年用户 1333经验值
私信 关注
[问答]

STM8S103F3P6实现两单片机的串口通讯,两指示灯都没亮是怎么回事?

本来刚接触STM8 单片机使用的是STM8S103F3P6,想法为想实现两单片机的串口通讯,主机发0x01  从机接如果收到0x01亮1指示灯,如果接收不是0x01亮另一指示灯,接收用中断,可两指示灯都没亮啊,根本没进中断,大侠们帮我看看是不是哪里配置有问题。

  1)硬件很简单  主:TX-从RX    主:RX-从:TX  中间接一1K电阻,TX   RX分别接有5.1K上拉电阻,5V供电

   2)发送程序如下:
   #include "iostm8s103f3.h"
/************************************/
/***************宏定义***************/
/************************************/
#define  ON   1
#define  OFF  0
#define POWER_LED   (PD_ODR_ODR3)    //电源显示  PD3
#define HIGHF_LED   (PA_ODR_ODR3)    //强风显示  PA3
#define BAOC_LED    (PA_ODR_ODR1)    //爆炒显示  PA1
#define LOWF_LED    (PC_ODR_ODR5)    //低风显示  PC5
#define LIGHT_LED   (PC_ODR_ODR4)    //照明显示  Pc4
/************************************/
/*************系统初始化*************/
/************************************/
void Sysinit(void)
{
  PA_DDR = 0xff;  //输出模式
  PA_ODR = 0xff;  //输出1
  PA_CR2 = 0x00;  //输出  2MHZ
  PA_CR1 = 0xff;  //推挽输出
  
  PB_DDR = 0xff;  //输出模式
  PB_ODR = 0xff;  //输出1
  PB_CR2 = 0x00;  //输出  2MHZ
  PB_CR1 = 0xff;  //推挽输出
  
  PC_DDR = 0xff;  //PC4输入 AD口
  PC_ODR = 0xff;  //PC4输出0 其他输出1  PC5  FTC334C电源初值为1
  PC_CR2 = 0x00;  //输出  2MHZ
  PC_CR1 = 0xff;  //推挽输出     PC4浮空输入
  
  //PD_DDR = 0xff;  //PD1 2 3 4 5 6 7输出模式
  //PD_ODR = 0xff;  //PD1 2 3 4 5 6 7输出1
// PD_CR2 = 0x00;  //输出  2MHZ
  //PD_CR1 = 0xdf;  //PD5 Tx开漏输出
  
  CLK_ICKR = 0x01; //bit 0开HSI时钟
  while(!CLK_ICKR_HSIRDY) ; //等待HSI时钟准备就绪
  CLK_ECKR = 0x00; //外部时钟关
  CLK_CKDIVR = 0x18;  //bit4-3  00:HSI/1  01:HSI/2 10:HSI/4 11:HSI/8 Tcpu=HSI/8=2MHZ
  CLK_PCKENR1 = 0x00;  //开tiM4时钟   其他外设时钟关
  CLK_PCKENR2 = 0x00;  //bit2 BEEP
  
}
//串口初始化函数
void USART_Init(void)
{
  PD_DDR  = ~(1<<5);
  PD_CR1 |= (1<<5);
  PD_ODR |= (1<<5);        
               
  PD_DDR  = ~(1<<6);
  PD_CR1 |= (1<<6);
  PD_ODR |= (1<<6);
  CLK_PCKENR1|= 0x04;  //开启串口时钟
  UART1_CR2 |= 0x00;    //发送禁止
  UART1_CR1 = 0x00;  //8位数据 不用奇偶校验
  UART1_CR3 = 0x00;  //1位停止位  不开启同步模式
  UART1_BRR2 = 0x00;  //9600  @2MHZ
  UART1_BRR1 = 0x0d;  //9600  @2MHZ
  UART1_CR2 |= 0x08;   //开启发送使能
  
}
void Send_Date(uint8_t date)
{
  while(!(UART1_SR 0x80))  ;    //等待发送数据寄存器空
  UART1_DR = date;
  while(!(UART1_SR 0x40))  ;   //等待发送完成
}
void main(void)
{
  Sysinit();
  USART_Init();
   Send_Date(0x01);
   
   //if(UART1_SR   0x80)  {HIGHF_LED = 0;}
   while(1) ;
}

3)接收程序如下:
   #include "iostm8s103f3.h"
/************************************/
/***************宏定义***************/
/************************************/
#define  ON   1
#define  OFF  0
#define POWER_LED   (PD_ODR_ODR3)    //电源显示  PD3
#define HIGHF_LED   (PA_ODR_ODR3)    //强风显示  PA3
#define LOWF_LED    (PC_ODR_ODR5)    //低风显示  PC5
#define LIGHT_LED   (PC_ODR_ODR4)    //照明显示  Pc4

uint8_t temp;                 
/************************************/
/*************系统初始化*************/
/************************************/
void Sysinit(void)
{
  PA_DDR = 0xff;  //输出模式
  PA_ODR = 0xff;  //输出1
  PA_CR2 = 0x00;  //输出  2MHZ
  PA_CR1 = 0xff;  //推挽输出
  
  PB_DDR = 0xff;  //输出模式
  PB_ODR = 0xff;  //输出1
  PB_CR2 = 0x00;  //输出  2MHZ
  PB_CR1 = 0xff;  //推挽输出
  
  PC_DDR = 0xff;  //PC4输入 AD口
  PC_ODR = 0xff;  //PC4输出0 其他输出1  PC5  FTC334C电源初值为1
  PC_CR2 = 0x00;  //输出  2MHZ   PD6禁止外部中断
  PC_CR1 = 0xff;  //推挽输出     PD6带上拉电阻输入
  
  //PD_DDR = 0xbf;  //PD6 输入模式  Rx 引脚
  //PD_ODR = 0xff;  //PD1 2 3 4 5 6 7输出1
// PD_CR2 = 0x00;  //输出  2MHZ
  //PD_CR1 = 0xff;  //推挽输出
  
  CLK_ICKR = 0x01; //bit 0开HSI时钟
  while(!CLK_ICKR_HSIRDY) ; //等待HSI时钟准备就绪
  CLK_ECKR = 0x00; //外部时钟关
  CLK_CKDIVR = 0x18;  //bit4-3  00:HSI/1  01:HSI/2 10:HSI/4 11:HSI/8 Tcpu=HSI/8=2MHZ
  CLK_PCKENR1 = 0xff;  //开TIM4时钟   其他外设时钟关
  CLK_PCKENR2 = 0xff;  //bit2 BEEP
  
}
void Delay_us(uint16_t us)
{
  while(us--) ;
}
void Delay_ms(uint16_t ms)
{
  uint16_t i;
  while(ms--)
  {
    for(i=0;i<1420;i++)
    {
      ;
    }
  }
}

//串口初始化函数
void USART_Init(void)
{
  //CLK_PCKENR1|= 0x04;  //开启串口时钟
  PD_DDR  = ~(1<<5);
  PD_CR1 |= (1<<5);
  PD_ODR |= (1<<5);        
               
  PD_DDR  = ~(1<<6);
  PD_CR1 |= (1<<6);
  PD_ODR |= (1<<6);
  UART1_CR1 = 0x00;  //8位数据 不用奇偶校验
  UART1_CR3 = 0x00;  //1位停止位  不开启同步模式
  UART1_BRR2 = 0x00;  //9600  @2MHZ
  UART1_BRR1 = 0x0d;  //9600  @2MHZ
  UART1_CR2 = 0x24;   //接收中断使能  开启接收使能
  asm("rim") ;       //允许CPU全局中断  STVD中为_asm("rim"); 开全局中断
}
#pragma vector=UART1_R_RXNE_vector
__interrupt void UART1_R_RXNE_vector_IRQHandler(void)
{
  temp = UART1_DR;
  if(temp == 0x01) {HIGHF_LED = 0;}
  else {LOWF_LED = 0;}
}
void main(void)
{
  Sysinit();
  USART_Init();
// LIGHT_LED = 0;
  
  while(1)  ;
}


回帖(2)

王伊

2024-5-13 16:38:47
先用串口调试助手每个单独调调吧
举报

秋风宜人

2024-5-13 18:07:18
首先,我们需要检查以下几个方面来确定问题所在:

1. 硬件连接:请确保您的硬件连接正确,包括单片机的TX和RX引脚、1K电阻以及5.1K上拉电阻。根据您的描述,硬件连接应该是正确的。

2. 串口配置:请检查您的串口配置是否正确。STM8S103F3P6的串口配置应该包括波特率、数据位、停止位和奇偶校验位。以下是配置串口的一个示例:

```c
void USART_Config(void) {
    /* 配置波特率为9600 */
    CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE);
    USART_Init(USART1, USART_BaudRate_9600, USART_WordLength_8D, USART_StopBits_1, USART_Parity_No);
    USART_Cmd(USART1, ENABLE);
}
```

3. 中断配置:请确保您的中断配置正确。您需要配置串口接收中断,并在中断服务程序中处理接收到的数据。以下是配置中断的一个示例:

```c
void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        uint8_t data = USART_ReceiveData(USART1);
        if (data == 0x01) {
            // 亮第一个指示灯
        } else {
            // 亮第二个指示灯
        }
    }
}
```

4. 主循环:在主循环中,您需要发送数据。以下是发送数据的一个示例:

```c
int main(void) {
    // 初始化串口
    USART_Config();

    while (1) {
        // 发送0x01
        USART_SendData(USART1, 0x01);
        // 延时一段时间,等待从机接收
        Delay(0x7D00);
    }
}
```

5. 检查指示灯控制:请确保您的指示灯控制代码正确。您需要根据接收到的数据来控制指示灯的亮灭。

如果以上步骤都正确无误,但问题仍然存在,请检查您的代码是否有语法错误或逻辑错误。此外,您还可以使用示波器或逻辑分析仪检查串口通信是否正常。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分