IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机 STC15W204S-35I SOP16 - UART,模式 1,使用定时器 2 作为波特率发生器 -> 正文阅读

[嵌入式]单片机 STC15W204S-35I SOP16 - UART,模式 1,使用定时器 2 作为波特率发生器

UART

原理图

在这里插入图片描述

模式 1

配置:

  • 1 个起始位, 8 位数据, 1 个停止位;
  • 使用定时器 2 作为波特率发生器;
  • 允许接收、发送请求中断;
  • 将接收到的数据直接发回去,并反转 P1.1 端口的电平。

工程结构:

在这里插入图片描述

stc15w204s.h 头文件:

  • 声明有关 UART 和定时器 0 的特殊功能寄存器;
  • 声明有关 UART 和定时器 0 的特殊功能寄存器的位掩码;
  • 以及其他。
#ifndef __STC15W204S_H
#define __STC15W204S_H


//#include<reg51.h>


#define INTERNAL_RC_OSCILLATOR_FREQUENCY_05529600HZ (5529600)  /*  5.5296 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_06000000HZ (6000000)  /*  6.0000 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_11059200HZ (11059200) /* 11.0592 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_12000000HZ (12000000) /* 12.0000 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_18432000HZ (18432000) /* 18.4320 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_20000000HZ (20000000) /* 20.0000 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_22118400HZ (22118400) /* 22.1184 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_24000000HZ (24000000) /* 24.0000 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_27000000HZ (27000000) /* 27.0000 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_30000000HZ (30000000) /* 30.0000 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_33177600HZ (33177600) /* 33.1776 MHz */
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_35000000HZ (35000000) /* 35.0000 MHz */

#define SYSTEM_CLOCK    (INTERNAL_RC_OSCILLATOR_FREQUENCY_11059200HZ)


/**
 * Interrupt Registers Definition
 */
sfr IE = 0xA8; /* Interrupt Enable Register */
sfr IE2 = 0xAF; /* Interrupt Enable 2 Register */

/**
 * Interrupt Registers Bits Definition
 */
/** IE */
#define GLOBAL_IE_EA    (0x80)
#define UART_IE_ES      (0x10) /* Enable UART interrupt request */
/** IE2 */
#define T2_IE2_ET2      (0x04) /* Timer 2 interrupt enable */


/**
 * Power Management Registers Definition
 */
sfr PCON    = 0x87; /* Power Control */

/**
 * UART Registers Definition
 */
sfr SCON    = 0x98; /* Serial Control */
sfr SBUF    = 0x99; /* Serial Buffer */

/**
 * UART Registers Bits Definition
 */
/** SCON */
#define UART_SCON_SM0   (0x80) /* UART - Serial Mode Selection Bit 0 */
#define UART_SCON_SM1   (0x40) /* UART - Serial Mode Selection Bit 1 */
#define UART_SCON_REN   (0x10) /* UART - Receiver Enable */
#define UART_SCON_TI    (0x02) /* UART - Transmission Completion Interrupt */
#define UART_SCON_RI    (0x01) /* UART - Reception Completion Interrupt */

sbit TI = SCON^1;
sbit RI = SCON^0;

/**
 * Timer 2 Registers Definition
 */
sfr T2L     = 0xD7; /* Timer 2 Counter Low Register */
sfr T2H     = 0xD6; /* Timer 2 Counter High Register */
sfr AUXR    = 0x8E; /* Auxiliary Register */

/**
 * Timer 2 Registers Bits Definition
 */
/** AUXR */
#define T2_AUXR_T2R     (0x10) /* Timer 2 - Run Control */
#define T2_AUXR_T2CT    (0x08) /* Timer 2 - Counter or Timer Selection */
#define T2_AUXR_T2x12   (0x04) /* Timer 2 - Speed Control */
#define UART_AUXR_S1ST2 (0x01) /* UART - Serial 1 (UART) Select Timer 2 Acts As Baud Rate Generator */


/**
 * Port 1 Registers Definition
 */
sfr P1 = 0x90; /* Port 1 Register */


typedef enum {
    FALSE = 0,
    TRUE = !FALSE
} boolean;


#define enableInterrupts(enable)    if(enable) {                \
                                        IE |= GLOBAL_IE_EA;     \
                                    } else {                    \
                                        IE &= ~GLOBAL_IE_EA;    \
                                    }                           

#endif

timer2.h 头文件:

#ifndef __STC15W204S_TIMER_2_H
#define __STC15W204S_TIMER_2_H


#include "stc15w204s.h"


typedef enum {
    TIMER2_PRESCALER_DIVIDED_BY_1   = 0,
    TIMER2_PRESCALER_DIVIDED_BY_12  = 12
} Timer2Prescaler;


typedef struct {
    void (*asTimer)(boolean);
    void (*setCounter)(unsigned int);
    void (*setTimer)(unsigned int);
    unsigned int (*getCounter)();
    unsigned int (*getTimer)();
    void (*setPrescaler)(Timer2Prescaler);
    void (*start)(boolean);
    void (*enableInterrupt)(boolean);
} Timer2;


extern Timer2 timer2;


/**
 * First call to this function to initialize
 * the <code>timer2</code> variable.
 */
void Timer2Constructor();


#endif

timer2.c 文件:

#include "timer2.h"


Timer2 timer2;


/**
 * If true, timer 2 acts as timer,
 * otherwise it acts as counter.
 */
static void asTimer(boolean isTimer) {
    if(isTimer) {
        AUXR &= ~T2_AUXR_T2CT;
    } else {
        AUXR |= T2_AUXR_T2CT;
    }
}

/**
 * Set the initial value of the counter
 * or the timer 2.
 */
static void setCounter(unsigned int counter) {
    T2H = (counter) >> 8;
    T2L = (counter) & 0xff;
}

/**
 * Return the value of the counter
 * or the timer 2.
 */
static unsigned int getCounter() {
    unsigned int counter;
    
    counter = T2H;
    counter = (counter << 8) | T2L;

    return counter;
}

/**
 * Set the prescaler of the timer 2.
 */
static void setPrescaler(Timer2Prescaler prescaler) {
    switch(prescaler) {
        case TIMER2_PRESCALER_DIVIDED_BY_1:
            AUXR |= T2_AUXR_T2x12;
            break;
        case TIMER2_PRESCALER_DIVIDED_BY_12:
            AUXR &= ~T2_AUXR_T2x12;
            break;
    }
}

/**
 * If true, start the timer 2 to run,
 * othewise, stop.
 */
static void start(boolean start) {
    if(start) {
        AUXR |= T2_AUXR_T2R;
    } else {
        AUXR &= ~T2_AUXR_T2R;
    }
}

/**
 * If true, enable timer 2 overflow
 * interrupt request, othewise, disable.
 */
static void enableInterrupt(boolean enable) {
    if (enable) {
        IE2 |= T2_IE2_ET2;
    } else {
        IE2 &= ~T2_IE2_ET2;
    }
}

void Timer2Constructor() {
    timer2.asTimer = &asTimer;
    timer2.setCounter = &setCounter;
    timer2.getCounter = &getCounter;
    timer2.setTimer = &setCounter;
    timer2.getTimer = &getCounter;
    timer2.setPrescaler = &setPrescaler;
    timer2.start = &start;
    timer2.enableInterrupt = &enableInterrupt;
}

uart.h 头文件:

#ifndef __STC15W204S_UART_H
#define __STC15W204S_UART_H


#include "stc15w204s.h"


typedef enum {
    UART_MODE_0   = ((unsigned char)0x00), // NO TEST!
    UART_MODE_1   = ((unsigned char)0x40),
    UART_MODE_2   = ((unsigned char)0x80), // NO TEST!
    UART_MODE_3   = ((unsigned char)0xC0)  // NO TEST!
} UartMode;

typedef enum {
    // In the STC15W204S SOP16, only Timer 2 is available for UART.
    UART_BAUD_RATE_GENERATOR_TIMER_2    = ((unsigned char)0x01)
} UartBaudRateGenerator;

typedef enum {
    UART_BAUD_RATE_1200     = (1200),
    UART_BAUD_RATE_2400     = (2400),
    UART_BAUD_RATE_4800     = (4800),
    UART_BAUD_RATE_9600     = (9600),
    UART_BAUD_RATE_14400    = (14400),
    UART_BAUD_RATE_19200    = (19200),
    UART_BAUD_RATE_28800    = (28800)
} UartBaudRate;

typedef enum {
    UART_INTERRUPT_FLAG_TX  = ((unsigned char)0x02),
    UART_INTERRUPT_FLAG_RX  = ((unsigned char)0x01)
} UartInterruptFlag;

typedef struct {
    void (*setMode)(UartMode);
    void (*selectBaudRateGenerator)(UartBaudRateGenerator);
    void (*setBaudRate)(UartBaudRate);
    void (*enableReceiver)(boolean);
    void (*clearInterruptFlag)(UartInterruptFlag);
    void (*enableInterrupt)(boolean);
} Uart;


extern Uart uart;


/**
 * First call to this function to initialize
 * the <code>uart</code> variable.
 */
void UartConstructor();


#endif

uart.c 文件:

#include "uart.h"


Uart uart;


/**
 * Set the mode of the UART.
 */
static void setMode(UartMode mode) {
    switch(mode) {
        case UART_MODE_0:
            SCON &= ~(UART_SCON_SM0 | UART_SCON_SM1);
            break;
        case UART_MODE_1:
            SCON &= ~UART_SCON_SM0;
            SCON |= UART_SCON_SM1;
            break;
        case UART_MODE_2:
            SCON |= UART_SCON_SM0;
            SCON &= ~UART_SCON_SM1;
            break;
        case UART_MODE_3:
            SCON |= (UART_SCON_SM0 | UART_SCON_SM1);
            break;
    }
}

/**
 * Set the baud rate generator for the UART communication.
 * Be careful, in the STC15W204S SOP16, Timer 1 is unavailable,
 * only the Timer 2 can be use as the UART baud rate generator.
 * So you must configure the Timer 2 for the UART.
 */
static void selectBaudRateGenerator(UartBaudRateGenerator baudRateGenerator) {
    switch(baudRateGenerator) {
        case UART_BAUD_RATE_GENERATOR_TIMER_2:
        default:
            AUXR |= UART_AUXR_S1ST2; // FORCE USE!
            break;
    }
}

/**
 * Set the baud rate of the UART communication.
 * Be careful, in the STC15W204S SOP16, Timer 1 is unavailable,
 * only the Timer 2 can be use as the UART baud rate generator.
 * So you must configure the Timer 2 for the UART.
 */
static void setBaudRate(UartBaudRate baudRate) {
    unsigned int counter;
    
    if((AUXR & T2_AUXR_T2x12) == T2_AUXR_T2x12) {
        counter = 65536 - (SYSTEM_CLOCK / baudRate / 4);
    } else {
        counter = 65536 - (SYSTEM_CLOCK / baudRate / 12 / 4);
    }
    
    T2H = (counter) >> 8;
    T2L = (counter) & 0xff;
}

/**
 * If true, enable the receiver,
 * otherwise, disable.
 */
static void enableReceiver(boolean enable) {
    if(enable) {
        SCON |= UART_SCON_REN;
    } else {
        SCON &= ~UART_SCON_REN;
    }
}

/**
 * Clears the UART interrupt request flag.
 */
static void clearInterruptFlag(UartInterruptFlag flag) {
    switch(flag) {
        case UART_INTERRUPT_FLAG_TX:
            SCON &= ~UART_SCON_TI;
            break;
        case UART_INTERRUPT_FLAG_RX:
            SCON &= ~UART_SCON_RI;
            break;
    }
}

/**
 * If true, enable UART interrupt request,
 * othewise, disable.
 */
static void enableInterrupt(boolean enable) {
    if (enable) {
        IE |= UART_IE_ES;
    } else {
        IE &= ~UART_IE_ES;
    }
}

void UartConstructor() {
    uart.setMode = &setMode;
    uart.selectBaudRateGenerator = &selectBaudRateGenerator;
    uart.setBaudRate = &setBaudRate;
    uart.enableReceiver = &enableReceiver;
    uart.clearInterruptFlag = &clearInterruptFlag;
    uart.enableInterrupt = &enableInterrupt;
}

main.c 文件:

/**
 * STC15W204S-35I SOP16
 * UART - Mode 1: 1 start bit, 8 bit data, 1 stop bit
 */

#include "timer2.h"
#include "uart.h"


sbit LED = P1^1;


void main() {
    UartConstructor();
    Timer2Constructor();
    
    // Timer 2 use for UART baud rate generator
    timer2.asTimer(TRUE);
    timer2.setPrescaler(TIMER2_PRESCALER_DIVIDED_BY_1);
    timer2.start(TRUE);
    
    uart.setMode(UART_MODE_1);
    uart.selectBaudRateGenerator(UART_BAUD_RATE_GENERATOR_TIMER_2);
    uart.setBaudRate(UART_BAUD_RATE_28800);
    uart.enableReceiver(TRUE);
    uart.clearInterruptFlag(UART_INTERRUPT_FLAG_TX);
    uart.clearInterruptFlag(UART_INTERRUPT_FLAG_RX);
    
    timer2.enableInterrupt(FALSE);
    uart.enableInterrupt(TRUE);
    
    enableInterrupts(TRUE);
    
    while(1) {}
}

void uartInterruptService() interrupt 4 {
    unsigned char buffer;
    
    if(RI) {
        RI = 0;
        buffer = SBUF; // Get
        SBUF = buffer; // Set
        
        LED = !LED;
    }
    
    if(TI) {
        TI = 0;
    }
}

下载、测试

呃,9600 的通信速度,数据出现丢失!不过可能和硬件有关,因为我使用了杜邦线,可能是导线过长导致的!

在这里插入图片描述

参考

宏晶科技 STC - STC15 系列单片机器件手册

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 11:22:14  更:2021-08-03 11:23:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 8:57:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码