2018-07-20 20:46:19 qq_36958104 阅读数 10968
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6014 人正在学习 去看看 朱有鹏

#include "config.h"

/******************************串口1的波特率********************************/
//T1作波特率发生器
//在波特率加倍情况下 
#define BAUD_57600                256 - (OSC_FREQ/192L)/57600L    // 254 FF
#define BAUD_28800                256 - (OSC_FREQ/192L)/28800L    // 254 FE
#define BAUD_19200                256 - (OSC_FREQ/192L)/19200L    // 253 FD
#define BAUD_14400                256 - (OSC_FREQ/192L)/14400L    // 252 FC
#define BAUD_9600                 256 - (OSC_FREQ/192L)/9600L     // 250 FA

#define SYS_Fosc        11059200L  //晶振频率               
uint32_t COMM_BAUD_RATE=9600  ;    //串口波特率
#define OSC_FREQ        11059200  //11059200  

static INT8U Send_buf[10] = {0} ;
static INT8U Recv_buf[10] = {0} ;


static INT8U SendDataLen = 0 ;
static INT8U ResendDataLen = 0 ;
/************************************************************************
函 数 名: 串口初始化
功能描述: STC10L08XE 单片机串口初始化函数
返回函数: none
其他说明: none
**************************************************************************/
void UartIni(void)
{
    TMOD = 0x20;                // 设置 T1 为波特率发生器
    SCON = 0x50;                // 0101,0000 8位数据位, 无奇偶校验
                           
    PCON = 0x00;                //PCON=0;

    TH1=256-(SYS_Fosc/COMM_BAUD_RATE/32/12);//设置为9600波特率
    TL1=256-(SYS_Fosc/COMM_BAUD_RATE/32/12);

    TR1     = 1;                //定时器1打开
    REN     = 1;               //串口1接收使能
    ES      = 1;               //串口1中断使能
      EA = 1;   
}
//串口接受函数初始化1
void UartIni1(void)
{
    SCON = 0x50;            //8-bit variable UART
    TMOD = 0x20;            //Set Timer1 as 8-bit auto reload mode
    TH1 = TL1 = -(SYS_Fosc/12/32/COMM_BAUD_RATE); //Set auto-reload vaule
    TR1 = 1;                //Timer1 start run
    ES = 1;                 //Enable UART interrupt
    EA = 1;                 //Open master interrupt switch
}
/***********************************************************
* 名    称: 
* 功    能: 
* 入口参数: 无 
* 出口参数:无
* 说    明:                      
**********************************************************/
void Uart_Isr() interrupt 4 using 1
{    
    if(RI)
    {    
          
    }

}
/************************************************************************
功能描述:     串口发送一字节数据  sbuf=data  
                接受     data=sbuf
入口参数:    DAT:带发送的数据
返 回 值:     none
其他说明:    none
**************************************************************************/
void Uart_PutByte(uint8_t DAT)
{
    ES  =  0;
    TI=0;
    DAT=SBUF  ;
    while(TI==0);
    TI=0;
    ES = 1;
}
///*****************************************************************************************************
// - 功能描述: 串口接受一帧数据
// - 隶属模块: 内部 
// - 参数说明: 
// - 返回说明: 
// - 注:无     
//*****************************************************************************************************/
void SendCmd(INT8U len )
{
    INT8U i = 0 ;
    for(i=0; i<len; i++)//数据
    {
        Uart_PutByte(Send_buf[i]) ;
    }
}

///********************************************************************************************
// - 功能描述:求和校验
// - 隶属模块:
// - 参数说明:
// - 返回说明:
// - 注:      和校验的思路如下
//             发送的指令,去掉起始和结束。将中间的6个字节进行累加,最后取反码
//             接收端就将接收到的一帧数据,去掉起始和结束。将中间的数据累加,再加上接收到的校验
//             字节。刚好为0.这样就代表接收到的数据完全正确。
//********************************************************************************************/
void DoSum( INT8U *Str, INT8U len)
{
    INT16U xorsum = 0;
    INT8U i;

    for(i=0; i<len; i++)
    {
        xorsum  = xorsum + Str[i];
    }
    xorsum     = 0 -xorsum;
    *(Str+i)   = (INT8U)(xorsum >>8);
    *(Str+i+1) = (INT8U)(xorsum & 0x00ff);
}


///********************************************************************************************
// - 功能描述: 串口向外发送命令[包括控制和查询]
// - 隶属模块: 外部
// - 参数说明: CMD:表示控制指令,请查阅指令表,还包括查询的相关指令
//              feedback:是否需要应答[0:不需要应答,1:需要应答]
//              data:传送的参数
// - 返回说明:
// - 注:       
//********************************************************************************************/
void Uart_SendCMD(INT8U CMD ,INT8U feedback , INT16U dat)
{
    Send_buf[0] = 0xff;    //保留字节 
    Send_buf[1] = 0x06;    //长度
    Send_buf[2] = CMD;     //控制指令
    Send_buf[3] = feedback;//是否需要反馈
    Send_buf[4] = (INT8U)(dat >> 8);//datah
    Send_buf[5] = (INT8U)(dat);     //datal
    DoSum(&Send_buf[0],6);        //校验
    SendCmd(8);       //发送此帧数据
}


/************************************************************************
功能描述: 串口发送字符串数据
入口参数:     *DAT:字符串指针
返 回 值: none
其他说明: API 供外部使用,直观!
**************************************************************************/
void PrintCom(uint8_t *DAT)
{
    while(*DAT)
    {
         Uart_PutByte(*DAT++);
    }    
}

/************************************************************************
功能描述: 串口发送字符串数据  直接发送 hex 文件 0x0f
                                               等价于 0f
入口参数:     *DAT:字符串指针
返 回 值: none
其他说明: API 供外部使用,直观!
**************************************************************************/
void PrintCom1(uint8_t *DAT)
{
    
    int i;
for(i=0;i<12;i++)
    {
         Uart_PutByte(*DAT++);  //Uart_PutByte   串口发送一字节数据  sbuf=data  
    }    
}


 

2018-11-03 18:44:51 qq_36958104 阅读数 8999
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6014 人正在学习 去看看 朱有鹏

include "config.h"

/******************************串口1的波特率********************************/
//T1作波特率发生器
//在波特率加倍情况下 
#define BAUD_57600 256 - (OSC_FREQ/192L)/57600L // 254 FF
#define BAUD_28800 256 - (OSC_FREQ/192L)/28800L // 254 FE
#define BAUD_19200 256 - (OSC_FREQ/192L)/19200L // 253 FD
#define BAUD_14400 256 - (OSC_FREQ/192L)/14400L // 252 FC
#define BAUD_9600 256 - (OSC_FREQ/192L)/9600L // 250 FA

 

#define SYS_Fosc 11059200L //晶振频率
uint32_t COMM_BAUD_RATE=9600 ; //串口波特率
#define OSC_FREQ 11059200 //11059200

static INT8U Send_buf[10] = {0} ;
static INT8U Recv_buf[10] = {0} ;


static INT8U SendDataLen = 0 ;
static INT8U ResendDataLen = 0 ;
/************************************************************************
函 数 名: 串口初始化
功能描述: STC10L08XE 单片机串口初始化函数
返回函数: none
其他说明: none
**************************************************************************/
void UartIni(void)
{
TMOD = 0x20; // 设置 T1 为波特率发生器
SCON = 0x50; // 0101,0000 8位数据位, 无奇偶校验

PCON = 0x00; //PCON=0;

TH1=256-(SYS_Fosc/COMM_BAUD_RATE/32/12);//设置为9600波特率
TL1=256-(SYS_Fosc/COMM_BAUD_RATE/32/12);

TR1 = 1; //定时器1打开
REN = 1; //串口1接收使能
ES = 1; //串口1中断使能
EA = 1; 
}
//串口接受函数初始化1
void UartIni1(void)
{
SCON = 0x50; //8-bit variable UART
TMOD = 0x20; //Set Timer1 as 8-bit auto reload mode
TH1 = TL1 = -(SYS_Fosc/12/32/COMM_BAUD_RATE); //Set auto-reload vaule
TR1 = 1; //Timer1 start run
ES = 1; //Enable UART interrupt
EA = 1; //Open master interrupt switch
}
/***********************************************************
* 名 称: 
* 功 能: 
* 入口参数: 无 
* 出口参数:无
* 说 明: 
**********************************************************/
void Uart_Isr() interrupt 4 using 1
{
if(RI)
{

}

}
/************************************************************************
功能描述: 串口发送一字节数据 sbuf=data 
接受 data=sbuf
入口参数: DAT:带发送的数据
返 回 值: none
其他说明: none
**************************************************************************/
void Uart_PutByte(uint8_t DAT)
{
ES = 0;
TI=0;
DAT=SBUF ;
while(TI==0);
TI=0;
ES = 1;
}
///*****************************************************************************************************
// - 功能描述: 串口接受一帧数据
// - 隶属模块: 内部 
// - 参数说明: 
// - 返回说明: 
// - 注:无 
//*****************************************************************************************************/
void SendCmd(INT8U len )
{
INT8U i = 0 ;
for(i=0; i<len; i++)//数据
{
Uart_PutByte(Send_buf[i]) ;
}
}

///********************************************************************************************
// - 功能描述:求和校验
// - 隶属模块:
// - 参数说明:
// - 返回说明:
// - 注: 和校验的思路如下
// 发送的指令,去掉起始和结束。将中间的6个字节进行累加,最后取反码
// 接收端就将接收到的一帧数据,去掉起始和结束。将中间的数据累加,再加上接收到的校验
// 字节。刚好为0.这样就代表接收到的数据完全正确。
//********************************************************************************************/
void DoSum( INT8U *Str, INT8U len)
{
INT16U xorsum = 0;
INT8U i;

for(i=0; i<len; i++)
{
xorsum = xorsum + Str[i];
}
xorsum = 0 -xorsum;
*(Str+i) = (INT8U)(xorsum >>8);
*(Str+i+1) = (INT8U)(xorsum & 0x00ff);
}


///********************************************************************************************
// - 功能描述: 串口向外发送命令[包括控制和查询]
// - 隶属模块: 外部
// - 参数说明: CMD:表示控制指令,请查阅指令表,还包括查询的相关指令
// feedback:是否需要应答[0:不需要应答,1:需要应答]
// data:传送的参数
// - 返回说明:
// - 注: 
//********************************************************************************************/
void Uart_SendCMD(INT8U CMD ,INT8U feedback , INT16U dat)
{
Send_buf[0] = 0xff; //保留字节 
Send_buf[1] = 0x06; //长度
Send_buf[2] = CMD; //控制指令
Send_buf[3] = feedback;//是否需要反馈
Send_buf[4] = (INT8U)(dat >> 8);//datah
Send_buf[5] = (INT8U)(dat); //datal
DoSum(&Send_buf[0],6); //校验
SendCmd(8); //发送此帧数据
}


/************************************************************************
功能描述: 串口发送字符串数据
入口参数: *DAT:字符串指针
返 回 值: none
其他说明: API 供外部使用,直观!
**************************************************************************/
void PrintCom(uint8_t *DAT)
{
while(*DAT)
{
Uart_PutByte(*DAT++);
}
}

/************************************************************************
功能描述: 串口发送字符串数据 直接发送 hex 文件 0x0f
等价于 0f
入口参数: *DAT:字符串指针
返 回 值: none
其他说明: API 供外部使用,直观!
**************************************************************************/
void PrintCom1(uint8_t *DAT)
{

int i;
for(i=0;i<12;i++)
{
Uart_PutByte(*DAT++); //Uart_PutByte 串口发送一字节数据 sbuf=data 
}
}

2019-11-12 18:03:23 ascending123 阅读数 239
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6014 人正在学习 去看看 朱有鹏

单片机串口通信:
通常的USB串行通信方式为全双工,即两条数据线:RXD和TXD,一条用于发送数据,一条用于接收数据。
在串行通信前,需要对串行通信进行配置。
对于单片机:
RI为接受中断标志位,未通信时RI=0;当电脑发送第一个字节帧a0到单片机时,SBUF=a0,中断标志位RI=1,单片机调用中断程序Usart(),在RI变为0之前,SBUF不能再读取串行数据,为了保证电脑上发送的数据都能被SBUF接收,中断程序中Usart()不应做逻辑处理

引用:http://www.openedv.com/thread-271758-1-1.html中的网友的话:
不要在中断里做逻辑处理,最好的是中断接收数据,保存在队列,另开任务,读取队列,处理数据

同样单片机发送时应当遵循下述步骤:
(未发送前TI=0)
1.SBUF=要发送的字节帧b0;
2.发送成功后TI=1;在此之前不能对SBUF做操作,所以在SBUF=b0后加入while(!TI);TI=1时循环结束
3.循环结束后将TI置0,字节帧发送完成。

PS:SBUF 为单片机里的两个寄存器,分别只有读和写的功能。

VISA中串口读写用的是字符串(char)

2019-01-15 23:06:18 qq_37007823 阅读数 862
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6014 人正在学习 去看看 朱有鹏

一、完整工程参考:示例工程源码(点击下载@akoc)

二、源码展示:

#define USART_RX_LEN 20  //接收缓存长度(请勿超过芯片rom剩余空间大小)  
#define USART_TX_LEN 20  //发送缓存长度                                                                
typedef struct      //串口相关结构体定义(主要用于接收):
{
    u8 RX_BUFF[USART_RX_LEN]; //接收缓存
    u8 TX_BUFF[USART_TX_LEN]; //发送缓存
    u16 RX_COUNT;
}USART;
USART Usart;

void USART_Configure(u16 BaudRate) //初使化函数  输入参数:波特率
{
    u8 TH1_Dat;
    
  switch(BaudRate) //采用switch提高可读性
    {
      case 1200:  TH1_Dat=0xE8; break;
        case 2400:  TH1_Dat=0xF4; break;
        case 4800:  TH1_Dat=0xFA; break;
        case 9600:  TH1_Dat=0xFD; break;
        case 14400: TH1_Dat=0xFE; break;
    }
    TMOD &= 0x0F;//先清除再配置
    TMOD |= 0x20;
    SCON &= 0x0F;
    SCON |= 0x50;
    TH1 = TH1_Dat;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 1;  
}

void USART_SendByte(u8 dat) //单字符发送
{
    SBUF=dat;
    while(!TI);  //等待发送数据完成
    TI=0;                //清除发送完成标志位
}
void USART_Send(u8* arr,u16 len)//多字符发送
{
  u16 i;
    for(i=0;i<len;i++)
    {
        SBUF=arr[i];
      while(!TI);  //等待发送数据完成
      TI=0;                //清除发送完成标志位  
    }
}
void USART_SendStr(u8* str)//字符串发送
{
  while(1)
    {
      if(*str=='\0') break;
        SBUF=*str++;
        while(!TI);  //等待发送数据完成
      TI=0;                //清除发送完成标志位
    }
}

void USART_IRQHandler(void) interrupt 4  //串口中断函数
{          
  if(RI==1)    //判断是否为接收中断(串口中断分为发送中断和接收中断,均用同一个中断服务函数入口)
    {
        RI = 0;    //清除RI硬件接收中断标志 
        Usart.RX_BUFF[Usart.RX_COUNT++]=SBUF;
        if(Usart.RX_COUNT==USART_RX_LEN) Usart.RX_COUNT=0;
    }    
}

//示例:

/*Uart串口发送函数示例:
1.USART_SendByte(u8 dat) //发送单字节数据
  例:USART_SendByte(0x04);

2.USART_Send(u8* arr,u16 len) //发送多字节数据
  例:
  Usart.TX_BUFF[0]=0xA1;
  Usart.TX_BUFF[1]=0x08;
  Usart.TX_BUFF[2]=0x04;
  Usart.TX_BUFF[3]=0xF9;
  USART_Send(Usart.TX_BUFF,4);
  或
  u8 Arr[16]={0xA1,0x08,0x04,0xF9};
  USART_Send(Arr,4);

3.USART_SendStr(u8* str) //发送字符串数据
  USART_SendStr("大吉在利,晚上吃鸡!\r\n");


Uart串口接收函数示例:
 

//1.单字符指令接收:

#include "reg51.h"
void main(void)
{
   USART_Configure(9600);//配置9600波特率(默认无奇偶校验,1位停止位,8位数据位)
   while(1)
     {
       if(Usart.RX_COUNT>0) //判断串口是否有接收
         {
           Usart.RX_COUNT=0;
             if(Usart.RX_BUFF[0]=='A') //如果控制对象比较多请换成switch()
             {
               P1=0x0F;
             }
             if(Usart.RX_BUFF[0]=='B')
             {
               P1=0xF0;
             }
         }
     }
}

//2.多字符指令接收:(为了方便,我们用C标准库自带的string.h)
#include "reg51.h"
#include <string.h>
void main(void)
{
   char xbuff[20];
   USART_Configure(9600);//配置9600波特率(默认无奇偶校验,1位停止位,8位数据位)
   while(1)
     {
       if(Usart.RX_COUNT>4) //判断串口是否接收到指令(设指令格式为:开灯/  关灯/  用/来表示指令结束符)
         {
           if(Usart.RX_BUFF[4]=='/') //断判结束符
             {
                 Usart.RX_COUNT=0;
                 strncpy(xbuff, Usart.RX_BUFF+0 , 4);//+0表示从接收缓存的第0个字符开始截取4个字符到xbuff判断指令
                 if(strncmp(xbuff,"开灯",4) == 0) 
                 {
                   P1=0x01;
                 }
                 if(strncmp(xbuff,"关灯",4) == 0) 
                 {
                   P1=~0x01;
                 }
             }
             else
             {
               Usart.RX_COUNT=0;
             }
     }
}

 

2013-02-24 15:00:31 autumn20080101 阅读数 2228
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6014 人正在学习 去看看 朱有鹏

【zacobin原创】瑞萨单片机串口下载仿真程序的硬件搭建和操作流程

分类: 编程开发 640人阅读 评论(0) 收藏 举报

瑞萨单片机可提供E8A和串口两种方式用于调试和下载程序,使用E8A调试比较简单都不需要什么配置就直接可以使用,很方便。但E8A仿真器价格高,对于个人玩玩的话再买个E8A来说可能不太划算,所以就动手整了下串口调试下载功能。该教程可以方便的实现串口调试下载功能。

一、开发平台:

操作系统:Windows XP

瑞萨开发环境:HEW

瑞萨烧写工具:FDT

使用单片机:L357C

参考文档:L357C单片机Datasheet,M16C/R8C FoUSB/UART软件用户手册

二、硬件原理

根据瑞萨L357C单片机Datasheet手册附录中,附录2:和串行编程器连接的例子。L357C单片机使用UART0作为串行编程器的通信口。原理图如下:


特别注意图中注1和注2,VREF直接接VCC即可,使用内部振荡器即可。

硬件连接按上图描述连接,连接到电脑串口即可。(RS232转TTL)


三、软件流程

1,使用FDT直接烧录mot文件,FDT的配置流程如下:

      打开瑞萨安装目录下的Flash Development Toolkit 4.08 Basic软件--->Option--->New Settings...--->在弹出Choose Device And Kernel中选择单片机型号:L357C 然后点击下一步--->在弹出Communications Port中选择COM1(实际连接电脑串口的串口号)然后下一步--->在弹出Connection Type中的Recommended Speeds选择38400或其他波特率,反选后面Use Default.然后下一步--->点击完成。然后就选择mot文件烧录即可。

2,使用HEW工程调试下载,配置流程如下:

新建项目流程和使用E8A调试的新建流程基本差不多,其中需要注意的就是需要选择编译器M16 R8C FoUSB/UART。(若没有该选择,则需要安装这个R8C_UART_MCU_INST_E.exe软件即可。)

连接好硬件设备后,点击HEW上的连接按钮会弹出下框:


这里需要注意几点:

1)选择的波特率一定要38400,选择其他波特率就不能通信(在这里折腾了很久才发现只有这样才可以)。

2)在烧录之前一定要先复位下单片机,再点击确定进行调试仿真,等下载完后就与用E8A仿真一样的效果了。

3)若使用的是USB转串口的话,可能波特率38400不支持,所以最好选择串口直接与电脑相连。

4)Mode脚一定要接地才可。


总结:使用串口仿真下载很方便,只需要在布板的时候多引出串口即可。这种方式便于生产时烧录程序,不需要E8A支持即可。


zacobin

2012-3-29



没有更多推荐了,返回首页