欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 656|回復(fù): 7
收起左側(cè)

關(guān)于STC8H4K64TL/STC8G1K08A單片機的串口問題

[復(fù)制鏈接]
ID:1167358 發(fā)表于 2026-2-8 21:01 | 顯示全部樓層 |閱讀模式
我使用STC官方(VSCode中EDIE插件下載的,有點區(qū)別)的串口寫入函數(shù)TX1_write2buff,但是燒錄到 STC8H4K64TL / STC8G1K08A 單片機,運行到TX1_write2buff后并沒有輸出(阻塞的方式是有輸出的),球大佬。
改了一下帖子,代碼精簡了一點。

這是我的主函數(shù)


#include "GPIO.h"
#include "UART.h"
#include "config.h"
#include "delay.h"/
#include <compiler.h>

// 串口波特率設(shè)置
#define BAUD 115200 // 波特率

void UART_Init()
{
    /* ===========================
     * UART1 參數(shù)配置
     * =========================== */
    COMx_InitDefine uart;

    uart.UART_Mode = UART_8bit_BRTx; // 8 位 UART,波特率發(fā)生器
    uart.UART_BRT_Use = BRT_Timer1;  // 使用 Timer1
    uart.UART_BaudRate = BAUD;
    uart.Morecommunicate = DISABLE;    // 不啟用多機通信
    uart.UART_RxEnable = ENABLE;       // 允許接收
    uart.BaudRateDouble = DISABLE;     // 不倍速,穩(wěn)定優(yōu)先
    uart.UART_Interrupt = ENABLE;      // 開 UART1 中斷
    uart.UART_Priority = Priority_0;   // ★最低優(yōu)先級★
    uart.UART_P_SW = UART1_SW_P30_P31; // P3.0 RX, P3.1 TX

    /* ===========================
     * 初始化 UART1
     * =========================== */
    int ret_code = UART_Configuration(UART1, &uart);

    /* ===========================
     * 初始化軟件狀態(tài)(很關(guān)鍵)
     * 防止上電或重入時臟數(shù)據(jù)
     * =========================== */
    ES = 0; // 關(guān)閉中斷

    COM1.TX_read = 0;
    COM1.TX_write = 0;
    COM1.B_TX_busy = 0;

    COM1.RX_Cnt = 0;
    COM1.RX_TimeOut = 0;
    COM1.B_RX_OK = 0;

    ES = 1; // 開啟中斷
}

// 發(fā)送一個字節(jié)
void UART_SendByte(unsigned char c)
{
    SBUF = c;
    while (!TI)
        ; // 等待發(fā)送完成
    TI = 0;
    // TX1_write2buff(c); // 這里取消注釋后,沒有雙倍的輸出!!!!!!!!!!!!!!!
}

// 接收一個字節(jié)
unsigned char UART_ReceiveByte()
{
    while (!RI)
        ; // 等待接收完成
    RI = 0;
    return SBUF;
}

void main()
{
    unsigned char c;
    UART_Init();

    // ES = 1;
    EA = 1;

    while (1)
    {
        c = UART_ReceiveByte(); // 接收數(shù)據(jù)
        UART_SendByte(c);       // 原封不動發(fā)送回去
    }
}


"""

這是我使用的UART.c(部分)
"""
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* 如果要在程序中使用此代碼,請在程序中注明使用了STC的資料及程序            */
/*---------------------------------------------------------------------*/

#include "UART.h"


#ifdef UART1
COMx_Define COM1;
u8  __xdata TX1_Buffer[COM_TX1_Lenth];  //發(fā)送緩沖
u8  __xdata RX1_Buffer[COM_RX1_Lenth];  //接收緩沖
#endif
#ifdef UART2
COMx_Define COM2;
u8  __xdata TX2_Buffer[COM_TX2_Lenth];  //發(fā)送緩沖
u8  __xdata RX2_Buffer[COM_RX2_Lenth];  //接收緩沖
#endif
#ifdef UART3
COMx_Define COM3;
u8  __xdata TX3_Buffer[COM_TX3_Lenth];  //發(fā)送緩沖
u8  __xdata RX3_Buffer[COM_RX3_Lenth];  //接收緩沖
#endif
#ifdef UART4
COMx_Define COM4;
u8  __xdata TX4_Buffer[COM_TX4_Lenth];  //發(fā)送緩沖
u8  __xdata RX4_Buffer[COM_RX4_Lenth];  //接收緩沖
#endif

u8 UART_Configuration(u8 UARTx, COMx_InitDefine *COMx)
{
    u8  i;
    u32 j;

#ifdef UART1
    if(UARTx == UART1)
    {
        COM1.id = 1;
        COM1.TX_read    = 0;
        COM1.TX_write   = 0;
        COM1.B_TX_busy  = 0;
        COM1.RX_Cnt     = 0;
        COM1.RX_TimeOut = 0;
        COM1.B_RX_OK    = 0;
        for(i=0; i<COM_TX1_Lenth; i++)  TX1_Buffer[ i] = 0;
        for(i=0; i<COM_RX1_Lenth; i++)  RX1_Buffer[ i] = 0;

        if(COMx->UART_Priority > Priority_3)    return 2;   //錯誤
        UART1_Priority(COMx->UART_Priority);    //指定中斷優(yōu)先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3
        if(COMx->UART_Mode > UART_9bit_BRTx)    return 2;   //模式錯誤
        SCON = (SCON & 0x3f) | COMx->UART_Mode;
        if((COMx->UART_Mode == UART_9bit_BRTx) || (COMx->UART_Mode == UART_8bit_BRTx))  //可變波特率
        {
            j = (MAIN_Fosc / 4) / COMx->UART_BaudRate;  //按1T計算
            if(j >= 65536UL)    return 2;   //錯誤
            j = 65536UL - j;
            if(COMx->UART_BRT_Use == BRT_Timer1)
            {
                TR1 = 0;
                AUXR &= ~0x01;      //S1 BRT Use Timer1;
                TMOD &= ~(1<<6);    //Timer1 set As Timer
                TMOD &= ~0x30;      //Timer1_16bitAutoReload;
                AUXR |=  (1<<6);    //Timer1 set as 1T mode
                TH1 = (u8)(j>>8);
                TL1 = (u8)j;
                ET1 = 0;    //禁止中斷
                TMOD &= ~0x40;  //定時
                INT_CLKO &= ~0x02;  //不輸出時鐘
                TR1  = 1;
            }
            else if(COMx->UART_BRT_Use == BRT_Timer2)
            {
                AUXR &= ~(1<<4);    //Timer stop
                AUXR |= 0x01;       //S1 BRT Use Timer2;
                AUXR &= ~(1<<3);    //Timer2 set As Timer
                AUXR |=  (1<<2);    //Timer2 set as 1T mode
                TH2 = (u8)(j>>8);
                TL2 = (u8)j;
                IE2  &= ~(1<<2);    //禁止中斷
                AUXR |=  (1<<4);    //Timer run enable
            }
            else return 2;  //錯誤
        }
        else if(COMx->UART_Mode == UART_ShiftRight)
        {
            if(COMx->BaudRateDouble == ENABLE)  AUXR |=  (1<<5);    //固定波特率SysClk/2
            else                                AUXR &= ~(1<<5);    //固定波特率SysClk/12
        }
        else if(COMx->UART_Mode == UART_9bit)   //固定波特率SysClk*2^SMOD/64
        {
            if(COMx->BaudRateDouble == ENABLE)  PCON |=  (1<<7);    //固定波特率SysClk/32
            else                                PCON &= ~(1<<7);    //固定波特率SysClk/64
        }
        if(COMx->UART_Interrupt == ENABLE)  ES = 1; //允許中斷
        else                                ES = 0; //禁止中斷
        if(COMx->UART_RxEnable == ENABLE)   REN = 1;    //允許接收
        else                                REN = 0;    //禁止接收
        P_SW1 = (P_SW1 & 0x3f) | (COMx->UART_P_SW & 0xc0);  //切換IO
        return  0;
    }
#endif
#ifdef UART2
    // 沒用到就刪了
#endif
#ifdef UART3
    // 沒用到就刪了
#endif
#ifdef UART4
    // 沒用到就刪了
#endif
    return  2;  //錯誤
}

/*********************************************************/

/********************* UART1 函數(shù) ************************/
#ifdef UART1
void TX1_write2buff(u8 dat) //寫入發(fā)送緩沖,指針+1
{
    TX1_Buffer[COM1.TX_write] = dat;    //裝發(fā)送緩沖
    if(++COM1.TX_write >= COM_TX1_Lenth)    COM1.TX_write = 0;

    if(COM1.B_TX_busy == 0)     //空閑
    {  
        COM1.B_TX_busy = 1;     //標志忙
        TI = 1;                 //觸發(fā)發(fā)送中斷
    }
}

void PrintString1(u8 *puts)
{
    for (; *puts != 0;  puts++)  TX1_write2buff(*puts);     //遇到停止符0結(jié)束
}

void UART1_int (void) __interrupt(UART1_VECTOR)
{
    if(RI)
    {
        RI = 0;
        if(COM1.B_RX_OK == 0)
        {
            if(COM1.RX_Cnt >= COM_RX1_Lenth)    COM1.RX_Cnt = 0;
            RX1_Buffer[COM1.RX_Cnt++] = SBUF;
            COM1.RX_TimeOut = TimeOutSet1;
        }
    }

    if(TI)
    {
        TI = 0;
        if(COM1.TX_read != COM1.TX_write)
        {
            SBUF = TX1_Buffer[COM1.TX_read];
            if(++COM1.TX_read >= COM_TX1_Lenth)     COM1.TX_read = 0;
        }
        else    COM1.B_TX_busy = 0;
    }
}
#endif

/********************* UART2 函數(shù) ************************/
// 沒用到就刪了


"""

這是我使用的UART.h
"""
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* 如果要在程序中使用此代碼,請在程序中注明使用了STC的資料及程序            */
/*---------------------------------------------------------------------*/

#ifndef __UART_H
#define __UART_H     

#include    "config.h"

#define UART1   1
//#define   UART2   2
//#define   UART3   3
//#define   UART4   4

#ifdef UART1
#define COM_TX1_Lenth   128
#define COM_RX1_Lenth   128
#endif
#ifdef UART2
#define COM_TX2_Lenth   128
#define COM_RX2_Lenth   128
#endif
#ifdef UART3
#define COM_TX3_Lenth   128
#define COM_RX3_Lenth   128
#endif
#ifdef UART4
#define COM_TX4_Lenth   128
#define COM_RX4_Lenth   128
#endif

#define UART_ShiftRight 0       //同步移位輸出
#define UART_8bit_BRTx  (1<<6)  //8位數(shù)據(jù),可變波特率
#define UART_9bit       (2<<6)  //9位數(shù)據(jù),固定波特率
#define UART_9bit_BRTx  (3<<6)  //9位數(shù)據(jù),可變波特率

#define UART1_SW_P30_P31    0
#define UART1_SW_P36_P37    (1<<6)
#define UART1_SW_P16_P17    (2<<6)
#define UART1_SW_P43_P44    (3<<6)
#define UART2_SW_P10_P11    0
#define UART2_SW_P46_P47    1
#define UART3_SW_P00_P01    0
#define UART3_SW_P50_P51    2
#define UART4_SW_P02_P03    0
#define UART4_SW_P52_P53    4


#define TimeOutSet1     5
#define TimeOutSet2     5
#define TimeOutSet3     5
#define TimeOutSet4     5

#define BRT_Timer1  1
#define BRT_Timer2  2
#define BRT_Timer3  3
#define BRT_Timer4  4

typedef struct
{
    u8  id;             //串口號

    u8  TX_read;        //發(fā)送讀指針
    u8  TX_write;       //發(fā)送寫指針
    u8  B_TX_busy;      //忙標志

    u8  RX_Cnt;         //接收字節(jié)計數(shù)
    u8  RX_TimeOut;     //接收超時
    u8  B_RX_OK;        //接收塊完成
} COMx_Define;

typedef struct
{
    u8  UART_Mode;          //模式,         UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
    u8  UART_BRT_Use;       //使用波特率,   BRT_Timer1,BRT_Timer2
    u32 UART_BaudRate;      //波特率,       ENABLE,DISABLE
    u8  Morecommunicate;    //多機通訊允許, ENABLE,DISABLE
    u8  UART_RxEnable;      //允許接收,   ENABLE,DISABLE
    u8  BaudRateDouble;     //波特率加倍, ENABLE,DISABLE
    u8  UART_Interrupt;     //中斷控制,   ENABLE,DISABLE
    u8  UART_Priority;      //優(yōu)先級,     Priority_0,Priority_1,Priority_2,Priority_3
    u8  UART_P_SW;          //切換端口,   UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
} COMx_InitDefine;

#ifdef UART1
extern  COMx_Define COM1;
extern  u8  __xdata TX1_Buffer[COM_TX1_Lenth];  //發(fā)送緩沖
extern  u8  __xdata RX1_Buffer[COM_RX1_Lenth];  //接收緩沖
#endif
#ifdef UART2
extern  COMx_Define COM2;
extern  u8  __xdata TX2_Buffer[COM_TX2_Lenth];  //發(fā)送緩沖
extern  u8  __xdata RX2_Buffer[COM_RX2_Lenth];  //接收緩沖
#endif
#ifdef UART3
extern  COMx_Define COM3;
extern  u8  __xdata TX3_Buffer[COM_TX3_Lenth];  //發(fā)送緩沖
extern  u8  __xdata RX3_Buffer[COM_RX3_Lenth];  //接收緩沖
#endif
#ifdef UART4
extern  COMx_Define COM4;
extern  u8  __xdata TX4_Buffer[COM_TX4_Lenth];  //發(fā)送緩沖
extern  u8  __xdata RX4_Buffer[COM_RX4_Lenth];  //接收緩沖
#endif

u8  UART_Configuration(u8 UARTx, COMx_InitDefine *COMx);
#ifdef UART1
void TX1_write2buff(u8 dat);    //寫入發(fā)送緩沖,指針+1
void PrintString1(u8 *puts);
#endif
#ifdef UART2
void TX2_write2buff(u8 dat);    //寫入發(fā)送緩沖,指針+1
void PrintString2(u8 *puts);
#endif
#ifdef UART3
void TX3_write2buff(u8 dat);    //寫入發(fā)送緩沖,指針+1
void PrintString3(u8 *puts);
#endif
#ifdef UART4
void TX4_write2buff(u8 dat);    //寫入發(fā)送緩沖,指針+1
void PrintString4(u8 *puts);
#endif

//void COMx_write2buff(COMx_Define *COMx, u8 dat);  //寫入發(fā)送緩沖,指針+1
//void PrintString(COMx_Define *COMx, u8 *puts);

#endif
回復(fù)

使用道具 舉報

ID:1167358 發(fā)表于 2026-2-9 08:24 | 顯示全部樓層
試了一下阻塞發(fā)送就沒問題。阻塞和非阻塞接收都沒問題。
回復(fù)

使用道具 舉報

ID:959346 發(fā)表于 2026-2-9 11:12 | 顯示全部樓層
對這顆芯片不熟,看情況是不是一直進中斷了?看看中斷觸發(fā)方式對不,中斷內(nèi)是否沒有清除好中斷標志?
回復(fù)

使用道具 舉報

ID:1167358 發(fā)表于 2026-2-9 12:06 | 顯示全部樓層
中斷內(nèi)部清除標志了
  1. void UART1_int (void) __interrupt(UART1_VECTOR)
  2. {
  3.         if(RI)
  4.         {
  5.                 RI = 0;
  6.                 if(COM1.B_RX_OK == 0)
  7.                 {
  8.                         if(COM1.RX_Cnt >= COM_RX1_Lenth)        COM1.RX_Cnt = 0;
  9.                         RX1_Buffer[COM1.RX_Cnt++] = SBUF;
  10.                         COM1.RX_TimeOut = TimeOutSet1;
  11.                 }
  12.         }

  13.         if(TI)
  14.         {
  15.                 TI = 0;
  16.                 if(COM1.TX_read != COM1.TX_write)
  17.                 {
  18.                          SBUF = TX1_Buffer[COM1.TX_read];
  19.                         if(++COM1.TX_read >= COM_TX1_Lenth)                COM1.TX_read = 0;
  20.                 }
  21.                 else        COM1.B_TX_busy = 0;
  22.         }
  23. }
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:1133081 發(fā)表于 2026-2-9 16:58 | 顯示全部樓層
STC官方示例就幾十條代碼,你洋洋灑灑幾百條代碼,把簡單問題復(fù)雜化。出了問題不好找。
回復(fù)

使用道具 舉報

ID:1167358 發(fā)表于 2026-2-9 17:39 | 顯示全部樓層
我那幾百行有stc官方庫啊。

我在stc8g1k08a上實驗也不行:

  1. #include "GPIO.h"
  2. #include "UART.h"
  3. #include "config.h"
  4. #include "delay.h"
  5. #include <compiler.h>

  6. // 串口波特率設(shè)置
  7. #define BAUD 115200 // 波特率

  8. void UART_Init()
  9. {
  10.     /* ===========================
  11.      * UART1 參數(shù)配置
  12.      * =========================== */
  13.     COMx_InitDefine uart;

  14.     uart.UART_Mode = UART_8bit_BRTx; // 8 位 UART,波特率發(fā)生器
  15.     uart.UART_BRT_Use = BRT_Timer1;  // 使用 Timer1
  16.     uart.UART_BaudRate = BAUD;
  17.     uart.Morecommunicate = DISABLE;    // 不啟用多機通信
  18.     uart.UART_RxEnable = ENABLE;       // 允許接收
  19.     uart.BaudRateDouble = DISABLE;     // 不倍速,穩(wěn)定優(yōu)先
  20.     uart.UART_Interrupt = ENABLE;      // 開 UART1 中斷
  21.     uart.UART_Priority = Priority_0;   // ★最低優(yōu)先級★
  22.     uart.UART_P_SW = UART1_SW_P30_P31; // P3.0 RX, P3.1 TX

  23.     /* ===========================
  24.      * 初始化 UART1
  25.      * =========================== */
  26.     int ret_code = UART_Configuration(UART1, &uart);

  27.     /* ===========================
  28.      * 初始化軟件狀態(tài)(很關(guān)鍵)
  29.      * 防止上電或重入時臟數(shù)據(jù)
  30.      * =========================== */
  31.     ES = 0; // 關(guān)閉中斷

  32.     COM1.TX_read = 0;
  33.     COM1.TX_write = 0;
  34.     COM1.B_TX_busy = 0;

  35.     COM1.RX_Cnt = 0;
  36.     COM1.RX_TimeOut = 0;
  37.     COM1.B_RX_OK = 0;

  38.     ES = 1; // 開啟中斷
  39. }

  40. // 發(fā)送一個字節(jié)
  41. void UART_SendByte(unsigned char c)
  42. {
  43.     SBUF = c;
  44.     while (!TI)
  45.         ; // 等待發(fā)送完成
  46.     TI = 0;
  47.     // TX1_write2buff(c);
  48. }

  49. // 接收一個字節(jié)
  50. unsigned char UART_ReceiveByte()
  51. {
  52.     while (!RI)
  53.         ; // 等待接收完成
  54.     RI = 0;
  55.     return SBUF;
  56. }

  57. void main()
  58. {
  59.     unsigned char c;
  60.     UART_Init();

  61.     // ES = 1;
  62.     EA = 1;

  63.     while (1)
  64.     {
  65.         c = UART_ReceiveByte(); // 接收數(shù)據(jù)
  66.         UART_SendByte(c);       // 原封不動發(fā)送回去
  67.     }
  68. }
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:1167358 發(fā)表于 2026-2-10 14:13 | 顯示全部樓層
已經(jīng)解決了!
結(jié)論是SDCC有點坑人,中斷函數(shù)不聲明在頭文件(UART.h)就直接優(yōu)化了,導(dǎo)致中斷函數(shù)沒有定義!
回復(fù)

使用道具 舉報

ID:1133081 發(fā)表于 2026-2-10 14:53 | 顯示全部樓層
fly-cloud 發(fā)表于 2026-2-9 17:39
我那幾百行有stc官方庫啊。

我在stc8g1k08a上實驗也不行:

這是用STC官方示例在STC8G1K08上測試的結(jié)果
無標題.jpg

  1. #include "stc8g.h"
  2. #include "intrins.h"

  3. #define FOSC        11059200UL
  4. #define BRT         (256 - FOSC / 115200 / 32)


  5. bit busy;
  6. char wptr;
  7. char rptr;
  8. char buffer[16];

  9. void UartIsr() interrupt 4
  10. {
  11.     if (TI)
  12.     {
  13.         TI = 0;
  14.         busy = 0;
  15.     }
  16.     if (RI)
  17.     {
  18.         RI = 0;
  19.         buffer[wptr++] = SBUF;
  20.         wptr &= 0x0f;
  21.     }
  22. }

  23. void UartInit()
  24. {
  25.     SCON = 0x50;
  26.     TMOD = 0x20;
  27.     TL1 = BRT;
  28.     TH1 = BRT;
  29.     TR1 = 1;
  30.     AUXR = 0x40;
  31.     wptr = 0x00;
  32.     rptr = 0x00;
  33.     busy = 0;
  34. }

  35. void UartSend(char dat)
  36. {
  37.     while (busy);
  38.     busy = 1;
  39.     SBUF = dat;
  40. }

  41. void UartSendStr(char *p)
  42. {
  43.     while (*p)
  44.     {
  45.         UartSend(*p++);
  46.     }
  47. }

  48. void main()
  49. {
  50.     P0M0 = 0x00;
  51.     P0M1 = 0x00;
  52.     P1M0 = 0x00;
  53.     P1M1 = 0x00;
  54.     P2M0 = 0x00;
  55.     P2M1 = 0x00;
  56.     P3M0 = 0x00;
  57.     P3M1 = 0x00;
  58.     P4M0 = 0x00;
  59.     P4M1 = 0x00;
  60.     P5M0 = 0x00;
  61.     P5M1 = 0x00;

  62.     UartInit();
  63.     ES = 1;
  64.     EA = 1;
  65.     UartSendStr("Uart Test !\r\n");

  66.     while (1)
  67.     {
  68.         if (rptr != wptr)
  69.         {
  70.             UartSend(buffer[rptr++]);
  71.             rptr &= 0x0f;
  72.         }
  73.     }
  74. }

復(fù)制代碼



回復(fù)

使用道具 舉報

ID:1167358 發(fā)表于 2026-2-10 16:46 | 顯示全部樓層
WL0123 發(fā)表于 2026-2-10 14:53
這是用STC官方示例在STC8G1K08上測試的結(jié)果

已經(jīng)解決了!
結(jié)論是SDCC有點坑人,中斷函數(shù)不聲明在頭文件(UART.h)就直接優(yōu)化了,導(dǎo)致中斷函數(shù)沒有定義!
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表