UART
原理图
模式 1
配置:
- 1 个起始位, 8 位数据, 1 个停止位;
- 使用定时器 2 作为波特率发生器;
- 允许接收、发送请求中断;
- 将接收到的数据直接发回去,并反转 P1.1 端口的电平。
工程结构:
stc15w204s.h 头文件:
- 声明有关 UART 和定时器 0 的特殊功能寄存器;
- 声明有关 UART 和定时器 0 的特殊功能寄存器的位掩码;
- 以及其他。
#ifndef __STC15W204S_H
#define __STC15W204S_H
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_05529600HZ (5529600)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_06000000HZ (6000000)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_11059200HZ (11059200)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_12000000HZ (12000000)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_18432000HZ (18432000)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_20000000HZ (20000000)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_22118400HZ (22118400)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_24000000HZ (24000000)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_27000000HZ (27000000)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_30000000HZ (30000000)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_33177600HZ (33177600)
#define INTERNAL_RC_OSCILLATOR_FREQUENCY_35000000HZ (35000000)
#define SYSTEM_CLOCK (INTERNAL_RC_OSCILLATOR_FREQUENCY_11059200HZ)
sfr IE = 0xA8;
sfr IE2 = 0xAF;
#define GLOBAL_IE_EA (0x80)
#define UART_IE_ES (0x10)
#define T2_IE2_ET2 (0x04)
sfr PCON = 0x87;
sfr SCON = 0x98;
sfr SBUF = 0x99;
#define UART_SCON_SM0 (0x80)
#define UART_SCON_SM1 (0x40)
#define UART_SCON_REN (0x10)
#define UART_SCON_TI (0x02)
#define UART_SCON_RI (0x01)
sbit TI = SCON^1;
sbit RI = SCON^0;
sfr T2L = 0xD7;
sfr T2H = 0xD6;
sfr AUXR = 0x8E;
#define T2_AUXR_T2R (0x10)
#define T2_AUXR_T2CT (0x08)
#define T2_AUXR_T2x12 (0x04)
#define UART_AUXR_S1ST2 (0x01)
sfr P1 = 0x90;
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;
void Timer2Constructor();
#endif
timer2.c 文件:
#include "timer2.h"
Timer2 timer2;
static void asTimer(boolean isTimer) {
if(isTimer) {
AUXR &= ~T2_AUXR_T2CT;
} else {
AUXR |= T2_AUXR_T2CT;
}
}
static void setCounter(unsigned int counter) {
T2H = (counter) >> 8;
T2L = (counter) & 0xff;
}
static unsigned int getCounter() {
unsigned int counter;
counter = T2H;
counter = (counter << 8) | T2L;
return counter;
}
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;
}
}
static void start(boolean start) {
if(start) {
AUXR |= T2_AUXR_T2R;
} else {
AUXR &= ~T2_AUXR_T2R;
}
}
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),
UART_MODE_1 = ((unsigned char)0x40),
UART_MODE_2 = ((unsigned char)0x80),
UART_MODE_3 = ((unsigned char)0xC0)
} UartMode;
typedef enum {
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;
void UartConstructor();
#endif
uart.c 文件:
#include "uart.h"
Uart 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;
}
}
static void selectBaudRateGenerator(UartBaudRateGenerator baudRateGenerator) {
switch(baudRateGenerator) {
case UART_BAUD_RATE_GENERATOR_TIMER_2:
default:
AUXR |= UART_AUXR_S1ST2;
break;
}
}
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;
}
static void enableReceiver(boolean enable) {
if(enable) {
SCON |= UART_SCON_REN;
} else {
SCON &= ~UART_SCON_REN;
}
}
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;
}
}
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 文件:
#include "timer2.h"
#include "uart.h"
sbit LED = P1^1;
void main() {
UartConstructor();
Timer2Constructor();
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;
SBUF = buffer;
LED = !LED;
}
if(TI) {
TI = 0;
}
}
下载、测试
呃,9600 的通信速度,数据出现丢失!不过可能和硬件有关,因为我使用了杜邦线,可能是导线过长导致的!
参考
宏晶科技 STC - STC15 系列单片机器件手册
|