基于51单片机的CAN通讯协议C语言程序
基于单片机的CAN总线通讯实现
基于单片机的CAN总线通讯实现CAN总线通讯是一种广泛应用于车辆电子系统、工业自动化和机器控制等领域的通讯协议,它具有高可靠性、实时性强和抗干扰能力强等优点。
在基于单片机的CAN总线通讯实现中,单片机作为CAN节点可以通过CAN总线与其他节点进行数据的发送和接收。
一、硬件搭建1.单片机选型在CAN总线通讯实现中,可以选择支持CAN总线的单片机芯片。
常见的单片机有STC12C5A60S2、AT89C51CC03等。
2.CAN总线收发器CAN总线收发器是实现单片机与CAN总线之间相互之间通信的关键组件。
常见的CAN收发器有TJA1050、SN65HVD230等。
3.连接线需要准备好与单片机芯片和CAN总线收发器相适应的连接线,如杜邦线等。
二、软件实现1.硬件初始化首先,在单片机中需要初始化相关的硬件资源,包括引脚设置、定时器设置等。
同时,也需要对CAN总线收发器进行初始化设置。
2.CAN总线配置在单片机中,需要配置CAN总线相关的寄存器,包括波特率设置、帧过滤设置等。
波特率的设置需要与其他CAN节点保持一致才可以正常通信。
3.数据发送单片机向CAN总线发送数据时,首先需要检查发送缓冲区是否为空。
如果不为空,则需要等待缓冲区可用,并将要发送的数据写入到发送缓冲区中。
随后,单片机向CAN总线发送一个请求发送的指令,然后等待发送完成的中断信号。
4.数据接收单片机接收CAN总线数据时,需要首先检查接收缓冲区是否为空。
如果接收缓冲区有数据,则单片机将读取缓冲区数据,并进行数据的处理。
5.中断处理CAN总线通讯中,可以通过中断的方式来处理数据的发送和接收。
单片机通过设置相关中断触发源和中断服务程序来实现数据的异步传输。
三、通讯协议CAN总线通讯中,可以使用标准CAN和扩展CAN两种协议。
标准CAN协议使用11位标识符,扩展CAN协议使用29位标识符。
在通讯过程中,需要设置相关的协议参数,包括标识符、数据长度码、帧类型等。
c51单片机c语言教程
51单片机C语言学习杂记学习单片机实在不是件易事,一来要购买高价格的编程器,仿真器,二来要学习编程语言,还有众多种类的单片机选择真是件让人头痛的事。
在众多单片机中51 架构的芯片风行很久,学习资料也相对很多,是初学的较好的选择之一。
51 的编程语言常用的有二种,一种是汇编语言,一种是 C 语言。
汇编语言的机器代码生成效率很高但可读性却并不强,复杂一点的程序就更是难读懂,而 C 语言在大多数情况下其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,而且 C 语言还可以嵌入汇编来解决高时效性的代码编写问题。
对于开发周期来说,中大型的软件编写用 C 语言的开发周期通常要小于汇编语言很多。
综合以上 C 语言的优点,我在学习时选择了 C 语言。
以后的教程也只是我在学习过程中的一些学习笔记和随笔,在这里加以整理和修改,希望和大家一起分享,一起交流,一起学习,一起进步。
*注:可以肯定的说这个教程只是为初学或入门者准备的,笔者本人也只是菜鸟一只,有望各位大侠高手指点错误提出建议。
明浩2003-3-30mailto:pnzwzw@ wzw@第一课建立您的第一个C项目使用C 语言肯定要使用到C 编译器,以便把写好的C 程序编译为机器码,这样单片机才能执行编写好的程序。
KEIL uVISION2 是众多单片机应用开发软件中优秀的软件之一,它支持众多不同公司的MCS51 架构的芯片,它集编辑,编译,仿真等于一体,同时还支持,PLM,汇编和C 语言的程序设计,它的界面和常用的微软VC++的界面相似,界面友好,易学易用,在调试程序,软件仿真方面也有很强大的功能。
因此很多开发51 应用的工程师或普通的单片机爱好者,都对它十分喜欢。
以上简单介绍了KEIL51 软件,要使用KEIL51 软件,必需先要安装它。
KEIL51 是一个商业的软件,对于我们这些普通爱好者可以到KEIL 中国代理周立功公司的网站上下载一份能编译2K 的DEMO 版软件,基本可以满足一般的个人学习和小型应用的开发。
51单片机的串口通信程序(C语言)
51单片机的串口通信程序(C语言) 51单片机的串口通信程序(C语言)在嵌入式系统中,串口通信是一种常见的数据传输方式,也是单片机与外部设备进行通信的重要手段之一。
本文将介绍使用C语言编写51单片机的串口通信程序。
1. 硬件准备在开始编写串口通信程序之前,需要准备好相应的硬件设备。
首先,我们需要一块51单片机开发板,内置了串口通信功能。
另外,我们还需要连接一个与单片机通信的外部设备,例如计算机或其他单片机。
2. 引入头文件在C语言中,我们需要引入相应的头文件来使用串口通信相关的函数。
在51单片机中,我们需要引入reg51.h头文件,以便使用单片机的寄存器操作相关函数。
同时,我们还需要引入头文件来定义串口通信的相关寄存器。
3. 配置串口参数在使用串口通信之前,我们需要配置串口的参数,例如波特率、数据位、停止位等。
这些参数的配置需要根据实际需要进行调整。
在51单片机中,我们可以通过写入相应的寄存器来配置串口参数。
4. 初始化串口在配置完串口参数之后,我们需要初始化串口,以便开始进行数据的发送和接收。
初始化串口的过程包括打开串口、设置中断等。
5. 数据发送在串口通信中,数据的发送通常分为两种方式:阻塞发送和非阻塞发送。
阻塞发送是指程序在发送完数据之后才会继续执行下面的代码,而非阻塞发送是指程序在发送数据的同时可以继续执行其他代码。
6. 数据接收数据的接收与数据的发送类似,同样有阻塞接收和非阻塞接收两种方式。
在接收数据时,需要不断地检测是否有数据到达,并及时进行处理。
7. 中断处理在串口通信中,中断是一种常见的处理方式。
通过使用中断,可以及时地响应串口数据的到达或者发送完成等事件,提高程序的处理效率。
8. 串口通信实例下面是一个简单的串口通信实例,用于在51单片机与计算机之间进行数据的传输。
```c#include <reg51.h>#include <stdio.h>#define BAUDRATE 9600#define FOSC 11059200void UART_init(){TMOD = 0x20; // 设置定时器1为模式2SCON = 0x50; // 设置串口为模式1,允许接收TH1 = 256 - FOSC / 12 / 32 / BAUDRATE; // 计算波特率定时器重载值TR1 = 1; // 启动定时器1EA = 1; // 允许中断ES = 1; // 允许串口中断}void UART_send_byte(unsigned char byte){SBUF = byte;while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志位}unsigned char UART_receive_byte(){while (!RI); // 等待接收完成RI = 0; // 清除接收完成标志位return SBUF;}void UART_send_string(char *s){while (*s){UART_send_byte(*s);s++;}}void main(){UART_init();UART_send_string("Hello, World!"); while (1){unsigned char data = UART_receive_byte();// 对接收到的数据进行处理}}```总结:通过以上步骤,我们可以编写出简单的51单片机串口通信程序。
独立CAN控制器SJA1000的C语言编程
SJA1000中断接收程序
unsigned char rx0; unsigned int rxide; unsigned char rxdata[8]; sbit rxsec=0; void receive interrupt 0 { unsigned char i; unsigned char *p; p=&rxide; rx0=RXEFF0; *p=RXEFF4; P++;
(ARM)设置 清零错误寄存器 中断使能寄存器(IER)设置 进入工作模式
SJA1000初始化程序
void sja1000_init( ) { MOD=0x09; CDR=0xc8;
OCR=0x1a; BTR0=0x??; BTR1=0x??; ACR0=0x??; ACR1=0x??; ACR2=0x??; ACR3=0x??;
ABSACC.H 提供的宏(Macro((unsigned char volatile code *) 0) #define DBYTE ((unsigned char volatile data *) 0) #define PBYTE ((unsigned char volatile pdata *) 0) #define XBYTE ((unsigned char volatile xdata *) 0) #define CWORD ((unsigned int volatile code *) 0) #define DWORD ((unsigned int volatile data *) 0) #define PWORD ((unsigned int volatile pdata *) 0) #define XWORD ((unsigned int volatile xdata *) 0)
51单片机can总线c语言程序,51单片机的can总线通讯程序
51单⽚机can总线c语⾔程序,51单⽚机的can总线通讯程序#i nclude//单⽚机头⽂件#i nclude//SJA存储器定义头⽂件#i nclude//SJA⼦程序⽂件/*************************函数声明*******************************************/void Init_T0(void); //初始化单⽚机T0void Sja_1000_Init(void); //初始化SJA//*******************************************************************bit flag_sec; //发送命令标志unsigned char data send_data[10],rcv_data[10];//发送和接收数组unsigned char sec_data,second; //定时器记数变量,发送数据变量unsigned char data Tmod_data; //定时器T0⼯作⽅式变量unsigned char bdata flag_init; //中断寄存器数据保存变量sbit rcv_flag=flag_init^0; //接收中断标志sbit err_flag=flag_init^2; //错误中断标志sbit P2_0=P2^0;sbit P3_4=P3^4;sbit LED=P3^5; //指⽰灯//***********************************************************void ex0_int(void) interrupt 0 using 1 //外部中断0{SJA_BCANAdr=REG_INTERRUPT; //指针指向中断寄存器flag_init=*SJA_BCANAdr; //保持中断寄存器值}//***********************************************************void T0_int(void) interrupt 1 using 2 //定时器T0中断服务⼦程序{TR0=0; //关闭定时器T0sec_data--; //秒计时变量减⼀if(sec_data==0) //2.25秒时间到了吗?{sec_data=0x50; //重新赋值TH0=0x80;TL0=0x60;flag_sec=1; //设置标志位second++; //发送的数据加⼀}TR0=1; //启动定时器T0}//************************************************************void Init_T0(void) //初始化定时器0{Tmod_data=TMOD;Tmod_data&=0xf0;Tmod_data|=0x01;TMOD=Tmod_data; //定时器T0⼯作⽅式设置TH0=0x80;TL0=0x60; //定时器T0初值设置TR0=1; //开放定时器T0sec_data=0x20; //记数值设置second=0x00; //发送数据初始化清零}//***********************************************************void Sja_1000_Init(void){BCAN_ENTER_RETMODEL(); //进⼊复位BCAN_SET_BANDRATE(0x0b); //800KBCAN_SET_OBJECT(0xaa,0xff); //设置地址ID:557BCAN_SET_OUTCLK(0xaa,0x48); //设置输出⽅式,禁⽌COLOCKOUT输出BCAN_QUIT_RETMODEL(); //退出复位模式SJA_BCANAdr=REG_CONTROL; //地址指针指向控制寄存器*SJA_BCANAdr|=0x1E; //开放错误\接收\发送中断}//*******************************************************************void main(void){P2_0=0; //SJA1000退出硬件复位模式Sja_1000_Init(); //initialize Sja100Init_T0(); //initialize T0PX0=1; //外部中断0⾼优先级IT0=1; //开放T0中断EX0=1; //外部中断0开放ET0=1; //开放外部中断0EA=1; //开放全局中断P3_4=0; //点亮指⽰灯flag_init=0x00; //变量清零while(1){if(rcv_flag) //if there is receive interrupt{ rcv_flag=0; //接收标志位清零BCAN_DATA_RECEIVE(rcv_data); //接收数据BCAN_CMD_PRG(0x04); //释放接收缓冲区}if(flag_sec){ flag_sec=0; //发送位清零send_data[0]=0xAA; //发送数据到ID为550的节点send_data[1]=0x08; //发送数据帧,8个字节长度send_data[2]=0x05; //第⼀个字节内容为数据05Hsend_data[3]=second; //第⼆个字节内容为变量值BCAN_DATA_WRITE(send_data); //发送数据BCAN_CMD_PRG(0x01); //置位发送请求位LED=~LED;}if(err_flag) //错误中断{ err_flag=0; //错误标志位清零Sja_1000_Init(); //初始化SJA}}}。
基于单片机的CAN总线通讯实现
基于单片机的CAN总线通讯实现CAN(Controller Area Network)总线是一种现代的串行通信总线,广泛应用于汽车电子系统和工控领域。
它具有高可靠性、抗干扰能力强、高速传输、多节点连接等特点,成为实时控制系统的首选通信方式。
实现基于单片机的CAN总线通讯,需要经过以下几个步骤:1.硬件准备:选择合适的CAN控制器和单片机,常用的CAN控制器有MCP2515、SJA1000等。
接下来需要连接CAN控制器和单片机,包括连接CAN高低线路、配置引脚等。
2.引脚配置:根据所使用的单片机和CAN控制器的规格,配置相应的引脚。
通常需要配置CAN_TX、CAN_RX引脚,同时还需要配置中断引脚。
3. 初始化CAN总线:初始化CAN总线的过程包括设置波特率、模式选择、滤波器设置等。
波特率是通信的重要参数,需要保证发送和接收端的波特率一致,通常使用比较常见的波特率如500kbps。
4.发送数据:CAN总线通信是基于消息的,发送数据需要构建CAN消息帧。
消息帧包括标识符、数据长度、数据内容等。
在发送数据之前,需要准备好发送的数据,并将数据放入CAN消息帧中,最后将消息帧发送到总线上。
5.接收数据:接收数据需要配置CAN总线的工作模式和接收过滤器。
当有数据从总线上接收时,CAN控制器将数据存入接收缓冲器,并产生中断或者置位标志位来提醒主控处理接收到的数据。
6.数据处理:接收到的数据可以根据需要进行处理,包括解析、判断、存储等。
根据数据的标识符和长度等信息,可以将数据分发给不同的处理程序进行处理。
7.错误处理:在CAN总线通信过程中,可能会出现数据错误、通信超时等问题。
需要设置相应的错误处理机制,包括错误标志位的监测、错误计数器的清零等。
8.电源管理:在使用CAN总线通信时,需要合理管理系统的功耗和电源。
对于低功耗应用,可以将CAN控制器和单片机配置为睡眠模式,待接收到唤醒信号后再恢复正常工作。
总结:基于单片机的CAN总线通讯实现需要进行硬件准备、引脚配置、初始化CAN总线、发送数据、接收数据、数据处理、错误处理和电源管理等一系列步骤。
基于51单片机的CAN总线系统设计
基于51单片机的CAN总线系统设计0 引言随着20世纪80年代初期德国Bosch公司提出CAN(Controller Area Network)总线,即控制器局域网方案以解决汽车控制装置问的通信问题。
经过20多年的发展,CAN总线现在广泛的应用在汽车领域,在汽车控制系统中应用CAN总线可以使硬件方案的软件化实现,大大地简化了设计,减小了硬件成本和设计生产成本,数据共享减少了数据的重复处理,节省了成本,可以将信号线减到最少,减少布线,使成本进一步降低等优点。
由于CAN总线通信的高性能、高可靠性、及独特的设计和适宜的价格可以广泛应用于工业现场控制、智能楼宇、医疗器械、交通工具以及传感器等领域,所以被公认为是几种最有前途的现场总线之一。
1 系统总体设计CAN总线系统总体结构如图1所示,主要包括上位机控制软件、USB-CAN转换模块、CAN节点、CAN总线介质(本处采用双绞线)组成。
其中一个CAN节点通过USB接口与PC 机相连,上位机控制软件能实时显示各CAN节点的数据且能通过上位机软件向各个CAN 节点发送数据以控制各节点的8个发光二极管的亮或灭。
2 系统硬件电路本系统由单片机外围电路、CAN总线硬件电路和USB-CAN转换电路组成。
单片机外围电路包括电源电路模块、复位电路模块、串口通信模块。
CAN总线硬件电路包括电气隔离模块、光耦隔离模块、CAN驱动器电路。
USB-CAN转换电路包括CH375与单片机接口电路模块和USB接口电路模块。
C8051F040单片机内部的控制器局域网(CAN)控制器是一个协议控制器,不提供物理层驱动器(即收发器),需要外部重新接入物理层驱动器。
本处采用TJ1050,TJA1050是控制器区域网络(CAN)协议控制器和物理总线之间的接口,是一种标准的高速CAN收发器。
TJA1050可以为总线提供差动发送性能,为CAN控制器提供差动接收性能。
TJA1050是PCA82C250和PCA82C251高速CAN收发器的后继产品。
51单片机的串口通信程序(C语言)
#include <reg52.h>#include<intrins.h>#include <stdio.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit Key1 = P2^3;sbit Key2 = P2^2;sbit Key3 = P2^1;sbit Key4 = P2^0;sbit BELL = P3^6;sbit CONNECT = P3^7;unsigned int Key1_flag = 0;unsigned int Key2_flag = 0;unsigned int Key3_flag = 0;unsigned int Key4_flag = 0;unsigned char b;unsigned char code Num[21]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00, 0x10,0x89};unsigned char code Disdigit[4] = {0x7F,0xBF,0xDF,0xEF};unsigned char Disbuf[4];void delayms(uint t){uint i;while(t--){/* 对于11.0592M时钟,约延时1ms */for (i=0;i<125;i++){}}}//-----------------------------------------------------void SendData(uchar Dat){uchar i=0;SBUF = Dat;while (1){if(TI){TI=0;break;}}}void ScanKey(){if(Key1 == 0){delayms(100); if(Key1 == 0){Key1_flag = 1; Key2_flag = 0; Key3_flag = 0;Key4_flag = 0;Key1 = 1;}else;}if(Key2 == 0){delayms(100);if(Key2 == 0){Key2_flag = 1; Key1_flag = 0; Key3_flag = 0;Key4_flag = 0;Key2 = 1;}else;}if(Key3 == 0){delayms(50);if(Key3 == 0){Key3_flag = 1; Key1_flag = 0; Key2_flag = 0;Key4_flag = 0;Key3 = 1;}else;}if(Key4 == 0){delayms(50);if(Key4 == 0){Key4_flag = 1;Key1_flag = 0;Key2_flag = 0;Key3_flag = 0;Key4 = 1;}else;}else;}void KeyProc(){if(Key1_flag){TR1 = 1;SendData(0x55);Key1_flag = 0; }else if(Key2_flag){TR1 = 1;SendData(0x11); Key2_flag = 0;}else if(Key3_flag) {P1=0xff;BELL = 0;CONNECT = 1;Key3_flag = 0;}else if(Key4_flag){CONNECT = 0;BELL = 1;Key4_flag = 0;}else;}void Initdisplay(void){Disbuf[0] = 1;Disbuf[1] = 2;Disbuf[2] = 3;Disbuf[3] = 4;}void Display() //显示{unsigned int i = 0;unsigned int temp,count;temp = Disdigit[count]; P2 =temp;temp = Disbuf[count];temp = Num[temp];P0 =temp;count++;if (count==4)count=0;}void time0() interrupt 1 using 2 {Display();TH0 = (65535 - 2000)/256;TL0 = (65535 - 2000)%256;}void main(){Initdisplay();TMOD = 0x21;TH0 = (65535 - 2000)/256;TL0 = (65535 - 2000)%256;TR0 = 1;ET0 = 1;TH1 = 0xFD; //11.0592MTL1 = 0xFD;PCON&=0x80;TR1 = 1;ET1 = 1;SCON = 0x40; //串口方式REN = 1;PT1 = 0;PT0 = 1;EA = 1;while(1){ScanKey();KeyProc();if(RI){Disbuf[0] = 0;Disbuf[1] = 20;Disbuf[2] = SBUF>>4;Disbuf[3] = SBUF&0x0f;RI = 0;}else;}}51单片机串口通信C语言程序2**************************************************************; 平凡单片机工作室;ckss.asm;功能:反复向主机送AA和55两个数;主机使用一个串口调试软件设置19200,n,8,1***************************************************************/#include "reg51.h"#define uchar unsigned char#define uint unsigned int//延时程序//////////////////由Delay参数确定延迟时间*/void mDelay(unsigned int Delay){ unsigned int i;for(;Delay>0;Delay--){ for(i=0;i<124;i++){;}}}//////////////////// 主程序////////////////////void main(){ uchar OutDat; //定义输出变量TMOD=0x20; //TMOD=0TH1=0xf3; //12MHZ ,BPS:4800,N,8,1TL1=0xf3;PCON=0x80; //方式一TR1=1; //?????????????????????????????SCON=0x40; //串口通信控制寄存器模式一OutDat=0xaa; //向串口发送固定数据值for(;;) //循环程序{SBUF=OutDat;//发送数据for(;;){ if(TI) //发送中断位当发送停止位时置1,表示发送完成break;}mDelay(500);TI=0; //清零中断位OutDat=~OutDat; //显示内容按位取反}}。
51单片机模拟can协议
51单片机模拟can协议51单片机是一种常见的嵌入式微控制器,具有广泛的应用。
CAN (Controller Area Network)协议是一种用于控制器之间通信的串行总线通信协议。
本文将介绍如何使用51单片机模拟CAN协议。
我们需要了解CAN协议的基本原理。
CAN协议是一种多主控制器、多节点的通信协议,用于在汽车、工业自动化等领域中实现控制器之间的高速、可靠通信。
CAN协议采用差分传输方式,通过两根线(CAN_H和CAN_L)进行数据传输。
CAN协议具有高抗干扰性、可靠性强等特点,因此在工业控制领域得到广泛应用。
要使用51单片机模拟CAN协议,我们首先需要了解CAN协议的基本通信过程。
CAN协议的通信过程包括以下几个步骤:帧的发送、帧的接收和错误处理。
在帧的发送过程中,发送节点将数据封装成CAN帧,并通过CAN总线发送给接收节点。
在帧的接收过程中,接收节点接收到CAN帧,并解析出其中的数据。
如果在通信过程中发生错误,CAN协议还提供了错误处理机制,可以及时检测和纠正错误。
在51单片机中模拟CAN协议的过程可以分为以下几个步骤:1. 配置51单片机的串口功能,使其能够模拟CAN总线的发送和接收功能。
可以通过设置串口的波特率、数据位、停止位等参数来实现。
2. 编写发送函数。
在发送函数中,我们需要将数据封装成CAN帧,并通过串口发送给接收节点。
可以使用51单片机的串口发送功能实现这一步骤。
3. 编写接收函数。
在接收函数中,我们需要通过串口接收CAN帧,并解析出其中的数据。
可以使用51单片机的串口接收功能实现。
4. 实现错误处理功能。
在通信过程中,可能会发生错误,如数据传输错误、帧格式错误等。
我们需要在程序中加入错误处理的代码,及时检测和纠正错误。
通过以上步骤,我们就可以在51单片机中模拟CAN协议的基本功能。
当然,要实现更复杂的功能,如多节点通信、数据校验等,还需要进一步深入学习CAN协议的相关知识和相关编程技巧。
51单片机两机串口通信c程序
51单片机两机串口通信c程序(共2页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--发送机#include<>#define uchar unsigned char#define uint unsigned intuchar code xuehao1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uchar code xuehao2[]={2,0,0,9,0,5,4,0,2,1,5,3};void send(uchar dat){SBUF=dat; //将待发送的数据写入发送缓存器中while(TI==0) //只要接收中断标志位; //空操作TI=0; //为了接收下一帧数据,需用软件降RI清零}void delay(){uchar m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}void main(){uchar i;TMOD=0x20;//定时器T1工作于方式2SCON=0x50;//串口工作方式1PCON=0x00;//电源控制寄存器,波特率不加倍TH1=0xfd; //波特率为 9600()TL1=0xfd;TR1=1; //启动定时器T1while(1){for(i=0;i<12;i++){send(xuehao1[xuehao2[i]]); //发送数据idelay();delay();delay();delay();}}}接受机#include<>#define uchar unsigned char#define uint unsigned intuchar receive(){uchar dat;while(RI==0); //只要接收中断标志位RI=0; //为了接收下一帧数据,需用软件降RI清零dat=SBUF; // 将接收缓存器中的数据存于datreturn dat; //将接收到的数据返回}void main(){TMOD=0x20;//定时器T1工作于方式2SCON=0x50;//串口工作方式1PCON=0x00;TH1=0xfd; //波特率为 9600()TL1=0xfd;TR1=1; //启动定时器T1REN=1; //允许接收while(1){P0=receive();}}。
[电子工程] 单片机C语言之串口通信协议(代码分享)
现实生活中,我们总是要与人打交道,互通有无。
单片机也一样,需要跟各种设备交互。
例如汽车的显示仪表需要知道汽车的转速及电动机的运行参数,那么显示仪表就需要从汽车的底层控制器取得数据。
而这个数据的获得过程就是一个通信过程。
类似的例子还有控制器通常是单片机或者PLC与变频器的通信。
通信的双方需要遵守一套既定的规则也称为协议,这就好比我们人之间的对话,需要在双方都遵守一套语言语法规则才有可能达成对话。
通信协议又分为硬件层协议和软件层协议。
硬件层协议主要规范了物理上的连线,传输电平信号及传输的秩序等硬件性质的内容。
常用的硬件协议有串口,IIC,SPI,RS485,CAN和USB。
软件层协议则更侧重上层应用的规范,比如modbus协议。
好了,那这里我们就着重介绍51单片机的串口通信协议,以下简称串口。
串口的6个特征如下。
(1)、物理上的连线至少3根,分别是Tx数据发送线,Rx数据接收线,GND共用地线。
(2)、0与1的约定。
RS232电平,约定﹣5V至﹣25V之间的电压信号为1,﹢5V至﹢25V之间的电压信号为0 。
TTL电平,约定5V的电压信号为1,0V电压信号为0 。
CMOS电平,约定3.3V的电压信号为1,0V电压信号为0 。
其中,CMOS电平一般用于ARM芯片中。
(3)、发送秩序。
低位先发。
(4)、波特率。
收发双方共同约定的一个数据位(0或1)在数据传输线上维持的时间。
也可理解为每秒可以传输的位数。
常用的波特率有300bit/s, 600bit/s, 2400bit/s, 4800bit/s, 9600bit/s。
(5)、通信的起始信号。
发送方在没有发送数据时,应该将Tx置1 。
当需发送时,先将Tx置0,并且保持1位的时间。
接受方不断地侦测Rx,如果发现Rx常时间变高后,突然被拉低(置为0),则视为发送方将要发送数据,迅速启动自己的定时器,从而保证了收发双方定时器同步定时。
(6)、停止信号。
发送方发送完最后一个有效位时,必须再将Tx保持1位的时间,即为停止位。
基于51单片机的CAN总线数据通信的设计与实现_张国兴
信息产业引言CAN总线是控制器局域网(ControllerAreaNet.work)总线的简称,属于现场总线范畴。
最初是以研发和生产汽车电子产品著称的德国Bosch公司开发的,是一种有效支持分布式控制或实时控制的串行通信网络[1]。
由于CAN总线具有通信速率高、可靠性高、连接方便及性能价格比高等诸多特点,在众多现场中占有较大的市场份额,所以CAN总线是目前国内外最普及和实时性最高的现场总线,基于CAN总线的电子产品有极为广泛的用途,CAN 总线标准及其技术日益成为国际关注的一大焦点[2]。
1CAN 总线技术及通信协议CAN是一种有效支持分布式控制或实时控制的串行通信网络。
CAN的应用范围遍及高速网络到低成本的多线路网络。
CAN总线的拓扑结构是一个典型的串行总线的结构形式,CAN总线支持基于报文的工作方式,加入或撤销节点设备都不会影响网络的工作,非常适用于要求实时快速、可靠简明控制系统中[3]。
当CAN总线上的一个节点(站)发送数据时,它以报文形式广播给网络中所有节点。
对每个节点来说,无论数据是否是发给自己的都对其进行接收。
每组报文开头的11位字符为标识符,定义了报文的优先级,这种报文格式称为面向内容的编址方案[4]。
在同一系统中标识符是唯一的,不可能有两个站发送具有相同标识符的报文。
2CAN 总线数据通信软件设计开发CAN总线系统,需要使用专门的CAN总线控制器。
基于CAN总线的CAN总线控制器具有完成CAN总线通信协议所要求的全部必要功能。
CAN总线控制器种类繁多,其中PHILIPS公司的SJA1000CAN控制器芯片以其良好的性能、极低的成本,获得了十分广泛的应用。
3CAN 总线通信模块的设计3.1初始化模块设计初始化程序主要是在程序运行前通过对CAN控制器SJA1000的控制段中的寄存器写入控制字,从而确定CAN控制器的工作方式等,使其能够按照用户需要的工作方式进行CAN总线通信。
在将这些配置信息配置到SJA1000配置寄存器后,通过消除复位模式请求使SJA1000进入操作模式。
基于51单片机SJA1000 CAN通讯实现
UART_Init(void){SCON=0X50;TMOD”=0X20;TH1=0XFD;TL1=0XFD;TR1=1;
EA=1;ES=1;}voidUART_Send_Byte(unsignedcharch){SBUF=ch;
while(!TI);//等到发送完成中断标志位置1TI=0;}void
if((state&0x20)==0x20)UART_Send_String(“SJA1000CANBUSis
transmiting!\r\n”);}}
2uart.h
#ifndef__UART_H__#define__UART_H__#include“stdio.h”#include
“reg51.h”#definereclength8externbitrecfinish;externunsignedchar
char num){P1=table[num];}
4sja1000.h
#ifndef__SJA1000_H__#define__SJA1000_H__#include“string.h”#include
含有输入参数unsigned char t,无返回值unsignedchar是定义无符号字符变量,
其值的范围是0~255这里使用晶振12M,精确延时请使用汇编,大致延时长度
如下T=tx2+5uS------------------------------------------------*/void
DelayUs2x(unsignedchart){while(--t);}/*------------------------------------------------
CAN的51单片机编程例子
//该程序运行在pic单片机p18f458上实现发送缓冲器0向接收缓冲器0发送数据的自测试模式,其中接收采用中断方式//发送采用查询方式#include "p18f458.h"int CAN_FLAG; //定义标志寄存器//**************初始化子程序***************// 单片机网提供有问题请联系我们void initcan(){TRISB=(TRISB|0X08)&0XFB; //设置CANRX/RB3为输入,CANTX/RB2为输出//设置CAN的波特率为125K,在Fosc=4M时,Tbit=8us,假设BRP=01h//则TQ=[2*(1+BRP)]/Fosc=2*(1+1)/4=1us。
//NOMINAL BIT RATE=8TQ,SJW=1,Sync_Seg=1TQ,Prog _Seg=1TQ,Phase_Seg1=3TQ,P hase_Seg2=3TQCANCON=0X80; //请求进入CAN配置模式REQOP=100while(CANSTAT&0X80==0){;} //等待进入CAN配置模式OPMODE=100BRGCON1=0X01; //设置SJW和BRP,SJW=1TQ,BRP=01HBRGCON2=0X90; //设置Phase_Seg1=3TQ和Prog _Seg=1TQBRGCON3=0X42; //设置Phase_Seg2=3TQ//设置发送邮箱0标识符号和发送的数据TXB0CON=0X03; //发送优先级为最高优先级,TXPRI=11TXB0SIDH=0XFF; //设置发送缓冲器0的标准标识符,本程序采用标准识符TXB0SIDL=0XE0;TXB0DLC=0X08; //设置数据长度为8个字节TXB0D0=0X00; //写发送缓冲器数据区的数据TXB0D1=0X01;TXB0D2=0X02;TXB0D3=0X03;TXB0D4=0X04;TXB0D5=0X05;TXB0D6=0X06;TXB0D7=0X07;//设置接收邮箱0的标识符和初始化数据RXB0SIDH=0XFF; //设置接收缓冲器0的标识符RXB0SIDL=0XE0;RXB0CON=0X20; //仅仅接收标准标识符的有效信息,FILHIT0=0表示RXB0采用filter0 RXB0DLC=0X08; //设置接收缓冲器0的数据区长度RXB0D0=0X00; //初始化接收缓冲器0的数据区数据RXB0D1=0X00;RXB0D2=0X00;RXB0D3=0X00;RXB0D4=0X00;RXB0D5=0X00;RXB0D6=0X00;RXB0D7=0X00;//初始化接收滤波器0和接收屏蔽,RXF0SIDH=0XFF;RXF0SIDL=0XE0;RXM0SIDH=0X00;RXM0SIDL=0X00;//初始化CAN模块的I/O控制寄存器//CIOCON=0X00;//使CAN进入某种工作模式模式CANCON=0X00; //=0X40,进入自测试模式;=0x00,正常操作模式 while(CANSTAT&0XE0!=0){;}//while(CANSTAT&0X40==0){;}//初始化CAN的中断PIR3=0X00; //清所有中断标志PIE3=0X01; //使能接收缓冲器0的接收中断IPR3=0X01; //接收缓冲器0的接收中断为最高优先级}//*********接收缓冲器0接收中断服务程序***********#pragma interrupt can_isr#pragma code low_ISR=0x18void low_ISR(){_asmgoto can_isr_endasm}#pragma codevoid can_isr(){if(PIR3bits.RXB0IF==1) CAN_FLAG=1;PIR3bits.RXB0IF=0; //清接收中断标志RXB0CONbits.RXFUL=0; //打开接收缓冲器来接收新信息}//****************主程序**can总线收发编程**************** main(){INTCON=0x00; //禁止所有中断initcan();WDTCON=0; //=1,看门狗使能;=0,禁止看门狗INTCON=0xc0; //使能中断while(1){TXB0CONbits.TXREQ=1; //请求发送,TXREQ=1while(PIR3bits.TXB0IF!=1){;} //等待发送完成while(CAN_FLAG==0){;} //等待接收数据CAN_FLAG=0; //清接收到标志TXB0CONbits.TXREQ=0; //禁止发送TXB0D0=RXB0D0+1; //用接收数据加1来更新发送数据 TXB0D1=RXB0D1+1;TXB0D2=RXB0D2+1;TXB0D3=RXB0D3+1;TXB0D4=RXB0D4+1;TXB0D5=RXB0D5+1;TXB0D6=RXB0D6+1;TXB0D7=RXB0D7+1;}}。
基于单片机的CAN总线通讯实现
CAN总线通讯基于51单片机应用第一章前言1.1 概述控制器局域网(CAN-Controller Area Network)属于现场总线(Fieldbus)的范畴,是众多的属于现场总线标准之一,它适用于工业控制系统,具有通信速率高、可靠性强、连接方便、性能价格比高等诸多特点。
它是一种有效支持分布式控制或实时控制的串行通信网络,以其短报文帧及CSMA/CD-AMP(带有信息优先权及冲突检测的载波监听多路访问)的MAC(媒介访问控制)方式而倍受工业自动化领域中设备互连的厚爱。
CAN的应用范围遍及从高速网络到低成本的多线路网络,它可以应用于汽车系统、机械、技术设备和工业自动化里几乎任何类型的数据通信。
随着计算机硬件、软件及集成电路技术的迅速发展,同时消费类电子产品、计算机外设、汽车和工业应用等的需求不断增加。
高速、高可靠和低成本的通信介质的要求也随之提高。
现场总线是当今自动化领域技术发展的热点之一,它为分布式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。
微处理器中常用的串行总线是通用异步接收器传输总线(UART)、串行通信接口(SCI)、同步外设接口(SPI)、内部集成电路(I2C)和通用串行总线(USB),以及车用串行总线,包括控制器区域网(CAN)和本地互连网(LIN)等。
这些总线在速度、物理接口要求和通信方法学上都有所不同。
在计算机数据传输领域内,长期以来使用的通信标准,尽管被广泛使用,但是无法在需要使用大量的传感器和控制器的复杂或大规模的环境中使用。
控制器局部网CAN(CONTROLLER AERANETW0RK)就是为适应这种需要而发展起来的。
随着汽车电子技术的发展,消费者对于汽车功能的要求越来越多,汽车上所用的电控单元不断增多,电控单元之间信息交换的需求,使得电子装置之间的通讯越来越复杂,同时意味着需要更多的连接信号线,这就促进了车用总线技术的发展。
CAN 总线的出现,就是为了减少不断增加的信号线,所有的外围器件都可以被连接到总线上由于CAN总线具有可靠性高、实时性好、成本合理等优点,逐渐被应用于如船舶、航天、工业测控、自动化、电力系统、楼宇监控等其他领域中。
以51单片机为例,一个简单的串口通信协议C程序
以51单片机为例,一个简单的串口通信协议C程序
/**************************************************
文件说明:以51 单片机为例,一个简单的串口通信协议C 程序,
协议以0XAA 开头,以0XCC,0X33,0XC3,0X3C 结尾,数据长度不一定
*************************************************/
#define uchar unsigned char
#define uint unsigned int
bit RXAAOK; //接收到0XAA 开头标志
bit RXFRMOK; //接收一帧完整数据标
//接收中断中如果是完整一条数据置位,主函数中
//处理完毕清零
uchar RXBUF[32]; //接收缓存
uchar RX_P; //数据个数
void UARTO_ISR() interrupt 4 //接收中断,不同处理器可能是不同的函数声明
{
uchar i; //用处提取接收缓冲器的字符
if(RI)
{ i=SBUF; //提取字符
RI=0;
if(RXFRMOK==0) //判断是否接收到起始字符0XAA
{ if(RXAAOK) //如果接收到0XAA,继续接收后面的字符
{ RXBUF[RX_P]=i; //字符存入数组。
51单片机can通信原理
51单片机can通信原理
51单片机CAN通信原理主要涉及到CAN总线的工作原理、硬件
连接和通信协议等方面。
首先,CAN(Controller Area Network)总线是一种串行通信
协议,用于在汽车、工业控制等领域中的实时控制系统中进行通信。
CAN总线采用差分信号进行通信,具有抗干扰能力强、传输距离远、传输速率高等特点。
在51单片机中,实现CAN通信需要通过CAN控制器和CAN总线
收发器来实现。
CAN控制器负责控制CAN总线的发送和接收,而CAN
总线收发器则负责将单片机的数字信号转换成CAN总线上的差分信号,并接收CAN总线上的差分信号并转换成数字信号供单片机处理。
在CAN通信中,数据通过CAN消息的形式进行传输。
CAN消息
由标识符(ID)和数据组成。
发送端通过CAN控制器将消息发送到CAN总线上,接收端通过CAN控制器接收并解析消息。
CAN总线采用CSMA/CR(Carrier Sense Multiple Access with Collision Resolution)协议,能够实现多个节点之间的协同工作,避免数据
冲突。
在硬件连接方面,需要将51单片机的CAN控制器和CAN总线收发器连接到CAN总线上,并通过电阻终端电阻来终止总线。
在软件开发方面,需要编写相应的CAN通信协议的驱动程序,实现CAN消息的发送和接收,并进行数据的解析和处理。
总的来说,51单片机CAN通信的原理涉及硬件连接、CAN消息的发送和接收、通信协议的实现等方面,需要综合考虑硬件和软件的设计。
希望这个回答能够全面地解答你的问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
// 入口函数 无
// 出口函数 无
// 全局变量 SJA_workmode
// 操作寄存器 控制寄存器(地址00)
// 函数功能 设置SJA工作在复位模式
#define SJA_RIE 0 //接收中断
//-----------------------定义地址指针,指向基址--------------------------------------------------------
bit bdata SJA_workmode=1; //SJA_workmode=1SJA工作在工作模式
//SJA_workmode=0工作在复位模式
#define base_Adr 0x00
//-----------------------定义总线定时寄存器的值--------------------------------------------------------
#define SJA_BTR0 0x00 //该值需要用户根据实际需要的波特率进行计算
//------------------------------------------------------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 CANREG_write
}BASICCAN_FRAME,receive_BUF,send_BUF;
//BASICCAN_BUFstruct send_BUF;
//------------------------------------------------------------------------------------------------------
//该值需要用户根据实际需要重新配置
#define SJA_ACR 0x00 //验收代码寄存器的值
#define SJA_AMR 0x16 //验收屏蔽寄存器的值
void SJAconnect_judge(void)
{
CANREG_write(0x09,0xAA); //写AA到测试寄存器(地址09)
if(CANREG_read(0x09)==0xAA)
{
connect_OK=1; //连接正常
#define SJA_OCR 0x00 //输出控制寄存器的值
#define SJA_CDR 0x16 //始终分频寄存器的值
//-----------------------设置SJA中断,1为开中断--------------------------------------------------------
{
SJA_workmode=0; //置复位模式成功
}
else
{
SJA_workmode=1; //置复位模式失败
#define SJA_OIE 0 //溢出中断
#define SJA_EIE 0 //错误中断
#define SJA_TIE 0 //发送中断
//-----------------------定义SJA1000读写缓冲区的数据结构--------------------------------------------------------
struct BASICCAN_BUFstruct{
unsigned char FrameID_H;
// 入口函数 SJAREG_ADR
// 出口函数 SJAREG_data
// 函数功能 读SJA1000的寄存器
//------------------------------------------------------------------------------------------------------
void CANREG_write(unsigned char SJAREG_ADR, unsigned char setting)
{
*(SJA_base_Adr+SJAREG_ADR)=setting;
}
//------------------------------------------------------------------------------------------------------
void setting_SJA_resetmode(void)
{
unsigned char CONTROL_REGdata;
// 入口函数 无
// 出口函数 无
// 全局变量 connect_OK
// 操作寄存器 测试寄存器(地址09)
// 函数功能 判断SJA1000与控制器连接是否正常
//------------------------------------------------------------------------------------------------------
unsigned char CANREG_read(unsigned char SJAREG_ADR)
{
unsigned char SJAREG_data;
SJAREG_data=*(SJA_base_Adr+SJAREG_ADR);
return(SJAREG_data);
}
else
{
connect_OK=0; //连接故障
}
}
//------------------------------------------------------------------------------------------------------
//-----------------------设置输出始终类型--------------------------------------------------------
//该值需要用户根据实际需要重新配置
}
//------------------------------------------------------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 SJAconnect_judge
unsigned char xdata *SJA_base_Adr = base_Adr;
//-----------------------定义硬件故障标志位--------------------------------------------------------
bit bdata connect_OK=0; //connect_OK=1设备连接正常
#define SJA_BTR1 0x16 //具体计算见文章说明
//-----------------------设置接收报文类型(标示符)--------------------------------------------------------
//connect_OK=0设备连接故障
//-----------------------定义硬件故障标志位--------------------------------------------------------
//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg52.h>
sbit int0 = P3^2;
//-----------------------定义寻址的基址--------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 CANREG_write
// 入口函数 SJAREG_ADR,setting
// 出口函数 无
// 函数功能 写SJA1000的寄存器
//------------------------------------------------------------------------------------------------------
unsigned char FrameLENTH ;
unsigned char FrameKIND ;
unsigned char FrameID_L3 ;
unsigned char Frame_Data[8];
CONTROL_REGdata=CANREG_read(0x00);
CONTROL_REGdata=CONTROL_REGdata|0x01;
CANREG_write(0x00,CONTROL_REGdata);
if((CANREG_read(0x00)&0x01)==1)