【问题标题】:PIC12F1572 UART Transmitter and receiver issuePIC12F1572 UART 发送器和接收器问题
【发布时间】:2025-12-15 12:15:02
【问题描述】:

我正在设计一个由 PIC12F1572 控制的 RGB LED 项目。我使用的软件是带有 XC8 编译器的 MPLAB IDE。计划是使用串行通信将 LED RGB 组合数据命令发送到 PIC 以存储在一个变量中,使其执行 LED 闪烁和发光。当我从 PC 终端发送 RGBFF00001FF001F0 并将其捕获在一个数组中但当我想查看我在数组中收集的值时,我再次 EUSART_Write(array) 然后我得到了每个字符之间有空格的值[R G B F F 0 0 0 0 1 F F 0 0 1 F 0 \n] 任何人都知道它是如何发生的,因为我的下一个任务取决于这个数组值。 我在这里分享我的代码: 任何关于在哪里可以找到这方面信息的提示或建议将不胜感激。

谢谢!

main.c

#include "mcc_generated_files/mcc.h"
#include <stdlib.h>
#include <stdio.h>
#include "atoh.h"
#include "LED.h"
#define _XTAL_FREQ 16000000
#define FRAMESIZE 18


void main(void)
{
   uint8_t data ,i,j;

   uint16_t R_value, G_value ,B_value;
   uint8_t value;
   uint8_t RX_Buffer[FRAMESIZE] = {0};
   uint8_t RGB_data[6] ,HEX_data[6];

    // initialize the device
    SYSTEM_Initialize();
    INTERRUPT_GlobalInterruptEnable();                       // Enable the Global Interrupts
    INTERRUPT_PeripheralInterruptEnable();                   // Enable the Peripheral Interrupts

   //  while(1)
   // {
   //    //EUSART_Write(0x61);
      while (!RCIF)
      {
          data = EUSART_Read();                              // Read received character
          for (i = 0; i<FRAMESIZE ; i++)
          {
            RX_Buffer[i] = data;
          }

          EUSART_Write(data); 
          EUSART_Write(RX_Buffer);       //HERE I RECHECK MY COLLECTED VALUE
         //check if any data is received
          }

            if(RX_Buffer[0]=='R' && RX_Buffer[FRAMESIZE-1] == '\n')
            {
              //ASCII to HEX separate values
              for (j = 0 ; j = 5; j++ )                   // get the RGB value in the separate array
                {
                    RGB_data[j] = RX_Buffer[j+3];
                    HEX_data[value] = RGB_data[j]/16;
                    EUSART_Write(HEX_data);
                }

              // uint32_t number = (uint32_t)strtol(HEX_data, NULL, 16);
              // R_value = number >>16;
              // G_value = (number & 0xffff) >> 8;
              // B_value = (number & 0x0000FF);

               R_value = (uint16_t) atoh(HEX_data[0], HEX_data[1]);
               G_value = (uint16_t) atoh(HEX_data[2], HEX_data[3]);
               B_value = (uint16_t) atoh(HEX_data[4], HEX_data[5]);
               EUSART_Write(R_value);
            }

               SetLedColor(R_value,G_value,B_value);



    } 

只装 UART.c

#include "eusart.h"
#include "LED.h"
#include <stdlib.h>
#include <stdio.h>
//#include "atoh.h"
/**
  Section: Macro Declarations
*/
#define EUSART_TX_BUFFER_SIZE 8
#define EUSART_RX_BUFFER_SIZE 8
#define _XTAL_FREQ 16000000
#define FRAMESIZE 18
/**
  Section: Global Variables
*/

static uint8_t eusartTxHead = 0;
static uint8_t eusartTxTail = 0;
static uint8_t eusartTxBuffer[EUSART_TX_BUFFER_SIZE];
volatile uint8_t eusartTxBufferRemaining;

static uint8_t eusartRxHead = 0;
static uint8_t eusartRxTail = 0;
static uint8_t eusartRxBuffer[EUSART_RX_BUFFER_SIZE];
volatile uint8_t eusartRxCount;


/**
  Section: EUSART APIs
*/

void EUSART_Initialize(void)
{
    // disable interrupts before changing states
    PIE1bits.RCIE = 0;
    PIE1bits.TXIE = 0;

    // Set the EUSART module to the options selected in the user interface.

    // ABDOVF no_overflow; SCKP Non-Inverted; BRG16 16bit_generator; WUE disabled; ABDEN disabled; 
    BAUDCON = 0x08;

    // SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled; 
    RCSTA = 0x90;

    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave; 
    TXSTA = 0x24;

    // Baud Rate = 9600; SPBRGL 160; 
    SPBRGL = 0xA0;

    // Baud Rate = 9600; SPBRGH 1; 
    SPBRGH = 0x01;


    // initializing the driver state
    eusartTxHead = 0;
    eusartTxTail = 0;
    eusartTxBufferRemaining = sizeof(eusartTxBuffer);

    eusartRxHead = 0;
    eusartRxTail = 0;
    eusartRxCount = 0;

    // enable receive interrupt
    PIE1bits.RCIE = 1;
}

uint8_t EUSART_Read(void)
{
    uint8_t readValue  = 0;

    while(0 == eusartRxCount)
    {
    }

    readValue = eusartRxBuffer[eusartRxTail++];
    if(sizeof(eusartRxBuffer) <= eusartRxTail)
    {
        eusartRxTail = 0;
    }
    PIE1bits.RCIE = 0;
    eusartRxCount--;
    PIE1bits.RCIE = 1;

    return readValue;
}



void EUSART_Write(uint8_t txData)
{
    while(0 == eusartTxBufferRemaining)
    {
    }

    if(0 == PIE1bits.TXIE)
    {
        TXREG = txData;
    }
    else
    {
        PIE1bits.TXIE = 0;
        eusartTxBuffer[eusartTxHead++] = txData;
        if(sizeof(eusartTxBuffer) <= eusartTxHead)
        {
            eusartTxHead = 0;
        }
        eusartTxBufferRemaining--;
    }
    PIE1bits.TXIE = 1;
}

void EUSART_Transmit_ISR(void)
{

    // add your EUSART interrupt custom code
    if(sizeof(eusartTxBuffer) > eusartTxBufferRemaining)
    {
        TXREG = eusartTxBuffer[eusartTxTail++];
        if(sizeof(eusartTxBuffer) <= eusartTxTail)
        {
            eusartTxTail = 0;
        }
        eusartTxBufferRemaining++;
    }
    else
    {
        PIE1bits.TXIE = 0;
    }
}

void EUSART_Receive_ISR(void)
{

    if(1 == RCSTAbits.OERR)
    {
        // EUSART error - restart

        RCSTAbits.CREN = 0;
        RCSTAbits.CREN = 1;
    }

    // buffer overruns are ignored
    eusartRxBuffer[eusartRxHead++] = RCREG;
    if(sizeof(eusartRxBuffer) <= eusartRxHead)
    {
        eusartRxHead = 0;
    }
    eusartRxCount++;
}

void EUSART_Put(const unsigned char *string)
{
    //int i;
    for (i=0;string[i]!='\0';i++)
    {
        EUSART_Write(string[i]);
    }
}

【问题讨论】:

    标签: pic uart mplab


    【解决方案1】:

    就像EUSART_Put() 一样,您应该始终使用用于通过UART 发送数据的包装函数,在整个地方单独调用EUSART_Write() 是一种不好的做法,错误可能来自EUSART_Write(R_value);,因为@ 987654324@ 在这里定义:

    uint16_t R_value, G_value ,B_value;
    

    您实际上是在发回 2 个字节(这就是空字节的来源)。

    【讨论】:

    • 我删除了那些 EUSART_Write() 并且只保留了 EUSART_Write(RX_Buffer);但仍然是相同的结果..我为此EUSART_Write(RX_Buffer [i])尝试更多;然后其他角色正在教角色之间进行评估..
    • 检查您的 UART 是否设置为发送 16 位字而不是 8 位字(一个字节),我不确定,但请查看初始化代码中的 BRG16 16bit_generator
    【解决方案2】:

    所以存储 UART 帧并回显是我的问题,我在这里通过我的方式解决了它。 这是我对此的回答。 代码:

    void main(void)
    {
       uint8_t data,i,j,got_char;
    
       uint8_t R_value, G_value ,B_value;
       uint8_t value;
       uint8_t RX_Buffer[FRAMESIZE];
       uint8_t RGB_data[6] ,HEX_data[6];
    
        // initialize the device
        SYSTEM_Initialize();
        INTERRUPT_GlobalInterruptEnable();                       // Enable the Global Interrupts
        INTERRUPT_PeripheralInterruptEnable();                   // Enable the Peripheral Interrupts
    
      while (1)
     {
    
            if (EUSART_DataReady)
            {
                for (i = 0; i<FRAMESIZE; i++)
                {
                    RX_Buffer[i] = EUSART_Read();
                    if (RX_Buffer[i] == '\n')
                       break;
                }
    
                RX_Buffer[i] = '\n';                        //append '\n' at the end of stoaring array for detection of frame
                RX_Buffer[i+1] = '\0';                      // End of an array
                EUSART_WriteAnArrayOfBytes(RX_Buffer);
    
    
            if(RX_Buffer[0]=='R' && RX_Buffer[FRAMESIZE-2] == '\n')   //check for correct frame
              {
    
                LATAbits.LATA2 = 1;
                __delay_ms(2000);
                LATAbits.LATA2 = 0;
                __delay_ms(1000);
              }
            }
    
      }       
    
    }
    

    【讨论】: