STC15 MCU 串口编程 proteus 仿真 SDCC51

1.STC单片机接口比传统的51单片机多得多,学起来更有意思。据说这种单片机得实际使用也很多,价格便宜,可以用来DIY。

2.KEIL是比较流行的编程工具,有点大,还需要license之类的,对于业余爱好用SDCC51也不错,更简洁。

3.proteus8.9中只有一个STC15单片机,先在网上找一些STC的资料

4.现代的单片机集成度高,一般不再外扩数据总线,串口用的比较多,类型也多。

5.STC15的串口和传统51兼容,但是proteus仿真还有些问题。

电路图如下,时钟复位都可选内置,proteus好像也不能仿真外置晶振和复位,干脆不画了。用虚拟示波器和虚拟终端配合调试。

 

 

双击MCU,在编辑固件中选用 之前已经下载安装好的SDCC51 自动创建程序框架,只需要改写一个main.c文件,proteus可以控制编译,仿真,源程序级调试,变量和寄存器观察,很方便。

1.对比了串口传统配置方式和STC15专用配置

2.新增寄存器的使用方法

3.SPI发送

4.SDCC51内嵌汇编的使用

 

/* Main.c file generated by New Project wizard
 *
 * Created:   2023-1-2
 * Processor: STC15W4K32S4
 * Compiler:  SDCC for 8051
 */

#include <mcs51reg.h>

#define sfr __sfr
#define idata __idata
#define xdata __xdata
#define interrupt __interrupt
#define using __using

#define     MAIN_Fosc            11059200L    
#define        Baudrate1                9600L

//SDCC51 特殊寄存器的定义方式
__sbit __at 0x97 LED_P1_7       ;  //P1_7

__sfr __at 0x8E AUXR         ;     //T0x12, T1x12, Uart M0x6, T2R
__sfr __at 0x8F AUXR2         ;     //T0x12, T1x12, Uart M0x6, T2R
__sfr __at 0xA2 AUXR1        ;     //s1[2],  cpp[2], spi[2], 0,DPS
__sfr __at 0xA2 P_SW1        ;
__sfr __at 0xAF IE2            ;
__sfr __at 0xCD SPSTAT      ;    //spif, wcol,  [6]
__sfr __at 0xCE SPCTL         ;    //ssig, spen, dord, mstr, cpol, cpha,  spr1, spr0
__sfr __at 0xCF SPDAT        ;

__sfr __at 0xD6 T2H        ;
__sfr __at 0xD7 T2L        ;

unsigned char xdata * pdata1;
unsigned char xdata  xdata2[10];

unsigned char xdata * p8255;

int i=0;
char rxc;
__bit flag = 0;
__bit flag_send = 0;

void timer0(void)   interrupt  1  using 1
{
EA =0; 
flag = !flag;
if(flag)
{
   //P1_7=0;
   LED_P1_7  = 0;
   i=0;
}
else
{
   //P1_7=1;
   LED_P1_7  = 1;
}
//TH0=0xff;       // STC15 mode 0 auto load
//TL0=0x16;  
EA =1;
}

void timer2(void)   interrupt  12  using 1
{
EA =0; 
EA =1;
}

void int1(void)   interrupt  2  using 2
{
EA =0; 
SBUF = 'W';
while(TI==0);
TI=0;
EA =1;
}

void serial(void)   interrupt  4  using 3
{
ES =0; 
if(RI)
{
 rxc = SBUF;
RI=0; 

SBUF = rxc;
flag_send = 1;
}
if(TI)
{
  TI=0; 
  flag_send = 0;
}
ES =1;
}

void send(char c) { while(flag_send); flag_send = 1; SBUF = c; } void sendstring(char* s) { while(*s) { send(*s++); } } void delay(int k) { int i; if(k< 0) return; for(i=0; i<k; i++); } //SDCC51 内嵌汇编的写法 void test_asm(void) { __asm ; This is a comment label: nop nop push acc push b push dpl push dph push psw mov acc, #0b11001100 mov psw,#0x00 inc acc pop psw pop dph pop dpl pop b pop acc __endasm; } void t0_init() { TMOD &= 0b11111100; TH0=0xff; // +1 TL0=0x80; TR0=1; //T0 start ET0 =1; //enable T0 int } void t2_init() { TMOD |= 0b00000001; // 0010 0010 T1,8bit auto timer, T0 16bit timer TMOD &= 0b11111101; AUXR |= 0b00010101; // T2 不分频 做 串口定时器 AUXR &= 0b11110111; //T2为定时器 AUXR2 &= 0b11111011; //禁止T2OUT IE2 &= 0b11111011; //禁止T2中断 TH2=0xff; // +1 TL2=0x80; //TR0=1; //T0 start //ET0 =1; //enable T0 int } void eint0_init() { IT1 = 1; // 1 -> 0 EX1=1; //enable int1 } //传统的8bit 配置方法,连续发送和中断收发都稳定,但是波特率高8倍 //新16bit法,中断收发不稳定,可能是仿真模型的问题,也可能配置还没弄对 void uart_init() { P_SW1 = P_SW1 & 0b00111111; // uart用P3口 #if 1 //传统的8bit 自动装载模式似乎速度8倍 AUXR &= 0b10111111; //传统模式 12分频 TMOD |= 0b00100000; // 0010 0010 T1,8bit auto timer, TMOD &= 0b11101111; SCON = 0X50; // 0101 0000 mode1 TH1=0XFD; // 76800 8倍 // 9600, 2^SMOD/32·T1 , 2^0/32*11059200 /12 /(256-0xfd)= 9600 TH1=0Xe8; // 9600, 2^SMOD/32·T1 , 2^0/32*11059200 /12 /(256-0xfd)= 9600 TL1=TH1; #else //改用STC15 新的16bit 自动装载模式 AUXR |= 0b01000000; //单时钟模式 TMOD &= 0b11001111; SCON = 0X50; // 0101 0000 mode1 8bit TH1=(65532 - (11059200 /4 /9600))>>8; // 9600, 2^SMOD/32·T1 , 2^0/32*11059200 /12 /(256-0xfd)= 9600 TL1=(65532 - (11059200 /4 /9600)); #endif PCON=0x00; //SMOD=0 , 0x80 SMOD=1 double ES=1; TR1=1; } //用T2 做波特率时钟 void uart_init_t2() { P_SW1 = P_SW1 & 0b00111111; // uart用P3口 AUXR |= 0b00010101; // T2 不分频 做 串口定时器 AUXR &= 0b11110111; //T2为定时器 AUXR2 &= 0b11111011; //禁止T2OUT IE2 &= 0b11111011; //禁止T2中断 SCON = 0X50; // 0101 0000 mode1 T2H=(65532 - (11059200 /4 /9600))>>8; // 9600, 2^SMOD/32·T1 , 2^0/32*11059200 /12 /(256-0xfd)= 9600 T2L=(65532 - (11059200 /4 /9600)); PCON=0x00; //SMOD=0 , 0x80 SMOD=1 double ES=1; TR1=1; } void spi_init() { P_SW1 = P_SW1 & 0b11110011; // SPI用P1口 SPDAT =0; SPSTAT = 0b11000000; //清除标志 SPCTL = 0b11010100; //SPI使能,主模式,clk/4 } void main(void) { EA=0; // disable all int uart_init(); //uart_init_t2(); t0_init(); //eint0_init(); spi_init(); EA =1; // enable all int //AUXR2 |= 0b00000010; //AUXR2 |= 0b00000100; sendstring("1.This is a test.\r\n"); sendstring("2.This is a test.\r\n"); while (1) { SPDAT =1; //send('a'); delay(100); test_asm(); } }

 

仿真运行,调试界面。

 

posted @ 2023-01-02 08:52  XGZ21  阅读(1033)  评论(0编辑  收藏  举报