第一次创建STC15串口程序模板


每次开始项目总是要从头开始,制作一个串口通讯程序作为模板是一个项目开始的好开端。

STC15W4K56S4最小系统

选择这款最小系统作为项目的开始为例,说明串口程序建立的过程。最小系统线路图如下:
在这里插入图片描述
注意,P55是最小系统的LED的驱动端口。

Keil编程

Keil软件是收费的软件,但以试验为目建立4K以下代码是允许的。

创建工程

创建工程选择Project->New μVersion Project…。
在这里插入图片描述
这里选择与STC15W4K56S4最接近的STC15W4K56S4作为模板来创建工程。

创建主程序

现在要为项目创建一个主程序。在文件菜单选择File -> New…。产生一个Text1的文件,另存这个文件为mian.c。右键点击Source Group 1,选择Add Files to Group ‘Source Group 1’…,出现如下的窗口:
在这里插入图片描述
在这其中选择刚才建立的main.c, 点击Add。

编辑主程序

主程序的编制比较简单

#include "USART.h"
#include "STC15Fxxxx.h"
#include "stdio.h"

void main(void)
{
 	u16  i;
 	u16 j;
 
 	UART_config();
 	printf("STC15W4K58S4 UART1 Setup OK!\r\n");
 	i++;
 	if ( i > 30000 )
 	{
  		printf("The i = %d\r\n", i);
 	}
 	while(1)
 	{
  		j++;
  		if ( j > 60000)
  		{
   			j = 0;
   			P55 = !P55;
   			printf("The P55 changed %d\r\n", (U16)P55);
  		}
	 }	
}

添加串口初始化及实现子文件


#include "USART.h"

void UART_config(void)
{
 COMx_InitDefine  COMx_InitStructure;     //结构定义
 COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;  //模式,    UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
 COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;   //使用波特率,   BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
 COMx_InitStructure.UART_BaudRate  = 115200ul;   //波特率, 一般 110 ~ 115200
 COMx_InitStructure.UART_RxEnable  = ENABLE;    //接收允许,   ENABLE或DISABLE
 COMx_InitStructure.BaudRateDouble = DISABLE;   //波特率加倍, ENABLE或DISABLE
 COMx_InitStructure.UART_Interrupt = ENABLE;    //中断允许,   ENABLE或DISABLE
 COMx_InitStructure.UART_Polity    = PolityLow;   //中断优先级, PolityLow,PolityHigh
 COMx_InitStructure.UART_P_SW      = UART1_SW_P30_P31; //切换端口,   UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17(必须使用内部时钟)
 COMx_InitStructure.UART_RXD_TXD_Short = DISABLE;  //内部短路RXD与TXD, 做中继, ENABLE,DISABLE
 USART_Configuration(USART1, &COMx_InitStructure);

 COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;  //模式,       UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
 COMx_InitStructure.UART_BaudRate  = 19200ul;   //波特率,     110 ~ 115200
 // 19200 made by cai
 COMx_InitStructure.UART_RxEnable  = ENABLE;    //接收允许,   ENABLE或DISABLE
 COMx_InitStructure.UART_Interrupt = ENABLE;    //中断允许,   ENABLE或DISABLE
 COMx_InitStructure.UART_Polity    = PolityLow;   //中断优先级, PolityLow,PolityHigh
 COMx_InitStructure.UART_P_SW      = UART2_SW_P46_P47; //切换端口,   UART2_SW_P10_P11,UART2_SW_P46_P47
 // UART2_SW_P10_P11 to UART2_SW_P46_P47
 USART_Configuration(USART2, &COMx_InitStructure);  //初始化串口2 USART1,USART2
}

COMx_Define COM1, COM2;
COMx_Define COM1,COM2;
u8 xdata TX1_Buffer[COM_TX1_Lenth]; //发送缓冲
u8  xdata RX1_Buffer[COM_RX1_Lenth]; //接收缓冲
u8 xdata TX2_Buffer[COM_TX2_Lenth]; //发送缓冲
u8  xdata RX2_Buffer[COM_RX2_Lenth]; //接收缓冲

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

 if(UARTx == USART1)
 {
  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_Mode > UART_9bit_BRTx) return 2; //模式错误  
  if(COMx->UART_Polity == PolityHigh)  PS = 1; //高优先级中断
  else         PS = 0; //低优先级中断
  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<<3); //定时
    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
  if(COMx->UART_RXD_TXD_Short == ENABLE) PCON2 |=  (1<<4); //内部短路RXD与TXD, 做中继, ENABLE,DISABLE
  else         PCON2 &= ~(1<<4);
  return 0;
 }

  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<<3); //定时
    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
  if(COMx->UART_RXD_TXD_Short == ENABLE) PCON2 |=  (1<<4); //内部短路RXD与TXD, 做中继, ENABLE,DISABLE
  else         PCON2 &= ~(1<<4);
  return 0;
 }

void PrintString2(u8 *puts)
{
    for (; *puts != 0; puts++)  TX2_write2buff(*puts);  //遇到停止符0结束
}

void UART_int (void) interrupt UART1_VECTOR
{
	if (RI)
	{
		RI = 0;
		if (COM1.B_RX_OK == 0)
		{
			if(COM1.RX_Cnt >= COM1_RX1_Length)  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;
  }

// UART2 中断程序
void UART2_int (void) interrupt UART2_VECTOR
{
 if(RI2)
 {
  CLR_RI2();
  if(COM2.B_RX_OK == 0)
  {
   if(COM2.RX_Cnt >= COM_RX2_Lenth) COM2.RX_Cnt = 0;
   RX2_Buffer[COM2.RX_Cnt++] = S2BUF;
   COM2.RX_TimeOut = TimeOutSet2;
  }
 }
// 发送控制
if(TI2)
{
	CLR_TI2();
	if(COM2.TX_read != COM2.TX_write)
	{
		S2BUF = TX2_Buffer[Com.TX_read];
		if(++COM2.TX_Read >= COM_TX2_Length)
			COM2.TX_read = 0;
	}
	else COM2.B_TX_busy = 0;
}
}

void putchar(char c){
    ES = 0;
    SBUF = c;
    while(TI==0);
    TI = 0;
    ES = 1;
}

在这里添加了一个putchar(char c)的函数,通过这个函数,可以实现printf程序,可以不用sprintf来格式化输出字符串。

下载程序

或者叫烧录程序,因为程序是下载到flash memory的,称之为烧录也不为过,在这里不能采用Keil直接下载,而是要用到STC-ISP程序,这个程序是STC厂家提供的,不需要安装,是直接可与i执行的程序,充满了国产软件的味道。没有安装,不需要注册,这就是国产软件。为我们国人所喜爱!只是CH340G的安装会遇到一些麻烦,但我的机器没有遇到麻烦。好像是其他的程序安装了驱动。
下载界面:
在这里插入图片描述
用运行助手看到的结果如上。

总结

用Kiel软件创建模板程序,为开发项目做前期准备,如果没有串口,调试程序几乎是不可能的。有了模板就可以方便的进行调试了。

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值