怎样编写单片机的串口通信的程序,一般的步骤是怎么样

怎样编写单片机的串口通信的程序,一般的步骤是怎么样,第1张

编戚野写串口通讯程序步滑滑骤为:

1、设置波特率

2、设置串口工作方式

3、收发数据

比如:

main()

{

unsigned char dat

TMOD=0x20

TH1=0xfd

TL1=0xfd

TR1=1

SCON=0x50

while(1)

    {

    while(RI==0)

    RI=0

    dat=SBUF

    SBUF=~dat

    while(TI==0)

    TI=0

  信仔腊  }

}

汇编编写的模拟串口通信程序

T2作为波特率控制

UART_RXD 是硬中断0或1口,如果能进入中断,说明该线有一个起始位产生,进入中断后调

用下面的接收程序。退出硬中断之前还需要将硬高镇中断标志重新复位。

UART_TXD 是任何其它IO即可。

UART_SEND:

PUSH IE

PUSH DPH

PUSH DPL

PUSH PSW

PUSH 00H

PUSH ACC

CLR EA

SETB UART_TXDSTART BIT

MOV R0,A

CLR TR2TR2置1,计数器2启动,时间计数启动。

MOV A,RCAP2L计数器2重新装载值

MOV TL2,A置计数器2初顷念扒值 T2需要重新装雀昌载

MOV A,DPH

MOV A,RCAP2H

MOV TH2,A

MOV A,R0

SETB TR2TR2置1,计数器

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2

CLR UART_TXDSTART BIT

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2

MOV R0,#08H

UART_SEND_LOOP:

RRC A

MOV UART_TXD,C8 BIT

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2

DJNZ R0,UART_SEND_LOOP

SETB UART_TXDEND BIT

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2

POP ACC

POP 00H

POP PSW

POP DPL

POP DPH

POP IE

RET

UART_REC:

PUSH IE

PUSH DPH

PUSH DPL

CLR EA

CLR TR2TR2置1,计数器2启动,时间计数启动。

MOV A,RCAP2L计数器2重新装载值

MOV TL2,A置计数器2初值 T2需要重新装载

MOV A,DPH

MOV A,RCAP2H

MOV TH2,A

JB UART_RXD,$REC

SETB TR2TR2置1,计数器2启动,时间计数启动。

JNB TF2,$

CLR TF20.5 BIT

JNB TF2,$

CLR TF21 BIT

JNB TF2,$

CLR TF21.5 BIT

MOV C,UART_RXD

MOV ACC.0,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF22.5

MOV C,UART_RXD

MOV ACC.1,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF23.5

MOV C,UART_RXD

MOV ACC.2,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF24.5

MOV C,UART_RXD

MOV ACC.3,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF25.5

MOV C,UART_RXD

MOV ACC.4,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF26.5

MOV C,UART_RXD

MOV ACC.5,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF27.5

MOV C,UART_RXD

MOV ACC.6,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF28.5

MOV C,UART_RXD

MOV ACC.7,C

JNB TF2,$

CLR TF29.5

JNB UART_RXD,$等待停止位,并重新复位计数器

SETB UART_RXD

POP DPL

POP DPH

POP IE

RET

补充回答:

串口调试

1. 发送:向总线上发命令

2. 接收:从总线接收命令,并分析是地址还是数据。

3. 定时发送:从内存中取数并向主机发送.

经过调试,以上功能基本实现,可以通过上位机对单片机进行实时控制。

程序如下:

//这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收

//和查询发送,发送没有必要用中断,因为程序的开销是一样的

#include <reg51.h>

#include<stdio.h>

#include <string.h>

#define INBUF_LEN 4 //数据长度

unsigned char inbuf1[INBUF_LEN]

unsigned char checksum,count3 , flag,temp,ch

bit read_flag=0

sbit cp=P1^1

sbit DIR=P1^2

int i

unsigned int xdata *RAMDATA/*定义RAM地址指针*/

unsigned char a[6] ={0x11,0x22,0x33,0x44,0x55,0x66}

void init_serialcomm(void)

{

SCON=0x50 //在11.0592MHz下,设置串行口波特率为9600,方式1,并允许接收

PCON=0x00

ES=1

TMOD=0x21 //定时器工作于方式2,自动装载方式

TH0=(65536-1000)%256

TL0=(65536-1000)/256

TL1=0xfd

TH1=0xfd

ET0=1

TR0=1

TR1=1

// TI=0

EA=1

// TI=1

RAMDATA=0x1F45

}

void serial () interrupt 4 using 3

{

if(RI)

{ RI=0

ch=SBUF

TI=1 //置SBUF空

switch(ch)

{

case 0x01 :printf("A") TI=0break

case 0x02 :printf("B") TI=0break

case 0x03 :printf("C") TI=0break

case 0x04 :printf("D") TI=0break

default :printf("fg") TI=0break

}

}

}

//向串口发送一个字符

void timer0() interrupt 1 using 3{

// char i

flag++

TH0=0x00

TL0=0x00

if(flag==10)

{// cp=!cp

// for(i=0i<6i++)

P2=0x25

TI=1

temp=*RAMDATA

printf("%c",temp)

TI=0

// RAMDATA--

flag=0

}

}

//主程序

main()

{

init_serialcomm() //初始化串口

//向6264中送数据

{

*RAMDATA=0x33

}

while(1)

{

*RAMDATA=0x33

}

}

调试需要注意的问题:

1. 发送过程:在发送时必须保证TI=1:即发送缓冲器为空,否则将导致数据发不出去,如果想强制发送可以用:TI=1.具体发送数据:利用printf(“abcd”)函数直接发送即可。

2. 接收过程:在接收时多选用中断方式,这样可以节约CPU的时间,提高效率,

C#串口 *** 作之读取串口数据:

try 

{  

axMSComm2.CommPort = 1i  

axMSComm2.InputMode =   

MSCommLib.InputModeConstants.comInputModeBinary  

//用于设置或返回传输数据的类型,  

//此例程是通过Input属性以二进制方式检取回数据  

axMSComm2.PortOpen = true  

//打开端口   

axMSComm2.InBufferCount = 0  

//用于返回输入缓冲区内销碧的等待读取得字节个数  

  

}  

catch (Exception e)  

{  

MessageBox.Show(e.ToString())  

}  

  

在axMSComm的OnComm事件里写:  

  

 private void axMSComm2_OnComm(object sender, EventArgs e)  

{  

  

switch (axMSComm2.CommEvent)  //查询CommEvent属性  

{  

case (short)(MSCommLib.OnCommConstants.comEvReceive):  

 //当接收缓冲区内字符数达到RThreshold值,  

//进入CommData()子程序  

  

  CommData() //接收缓冲区内数据  

  break  

}  

  

}  

  

 private void CommData() //接收数据  

{  

int BufferDataNumStart = 0  

 //定义第一次查询缓冲区内数据个数  

int BufferDataNumEnd = 0   

//定义最后一次查询缓冲区内数据个数  

byte[] CommBufferData = new byte[1024]  

byte[] ComByte = new byte[8]  

  

BufferDataNumStart = axMSComm2.InBufferCount    

//将缓冲区内等待读取的字节个数赋给BufferDataNumStart  

if (BufferDataNumStart == 0) return   

//如果缓冲区为空,说明还没有数据传来,  

//则返回;若不为空,进入下面的循环  

//读取缓冲区内全部内容  

axMSComm2.InputLen = 0  

while (true)  

{  

System.Threading.Thread.Sleep(50)   

//延时,以确保数据完全接收  

BufferDataNumEnd = axMSComm2.InBufferCount  

//再次读取缓冲区内字节个陪液数  

if (BufferDataNumStart == BufferDataNumEnd) break   

//如果BufferDataNumStart==BufferDataNumEnd,  

//说明本亏乱举帧数据已经读完,退出循环  

BufferDataNumStart = BufferDataNumEnd   

//否则,将BufferDataNumEnd赋给BufferDataNumStart,  

//并继续循环,直到完全接收  

}  

object objIn  

objIn = axMSComm2.Input   

//这里注意MSComm.Input返回的是一个object的类型,  

//所以必须使用显式的类型转换   

CommBufferData = (byte[])objIn     

//CommBufferData为串口缓冲区内所有数据  

//存取最后一次接收到的缓冲区的数据,  

//存储部分时作为后期数据处理所用,  

//以便于程序员分析数据。使用StreamWriter,  

//需在添加命名控件using System.IO  

  

//将上次未处理的数据和本次存储数据在ReceivedData相连,  

//此部分是防止发送过来的数据本身就不完整,  

//以至于数据处理不能进行完全,故保留并与新接收的数据相连  

for (int i = 0 i < BufferDataNumEnd i++)  

{  

ReceiveDataNum++  

UnsettledDataNum++  

ReceivedData[ReceiveDataNum - 1] = CommBufferData[i]  

}  

//进入数据处理字程序  

  

}  

private void DealData() //数据处理  

{  

  

for (int i = 0 i < ReceivedData.Length - 7 i++)  

{  

if (ReceivedData[i] ==   

0xff && ReceivedData[i + 1] == 0x04)判断通讯头  

{  

  

zhou++  

INTzhouzhong[zhou] =   

int.Parse(ReceivedData[i + 4].ToString("X")) * 10000 +   

int.Parse(ReceivedData[i + 3].ToString("X")) * 100 +  

 int.Parse(ReceivedData[i + 2].ToString("X"))  

}  

}  

ReceiveDataNum = 0  

UnsettledDataNum = 0  

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/8186281.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-14
下一篇2023-04-14

发表评论

登录后才能评论

评论列表(0条)

    保存