程序硬件平台:11.0592M晶振,
/***************************************************************
*在单片机上模拟了一个串口,使用P2.1作为发送端
*把单片机中存放的数据通过P2.1作为串口TXD发送出去
***************************************************************/
#include <reg51.h>
#include <stdio.h>
#include <string.h>
typedef unsigned char uchar
int i
uchar code info[] =
{
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
}
sbit newTXD = P2^1//模拟串口的发送端设为P2.1
void UartInit()
{
SCON = 0x50 // SCON: serail mode 1, 8-bit UART
TMOD |= 0x21 // T0工高悄逗作在方式1,十六位定时
PCON |= 0x80 // SMOD=1
TH0 = 0xFE // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=11.0592MHz
TL0 = 0x7F // 定时运斗器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=11.0592MHz
//TH0 = 0xFD // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18.432MHz
//TL0 = 0x7F // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18.432MHz
}
void WaitTF0(void)
{
while(!TF0)
TF0=0
TH0=0xFE // 定时器重装初值 fosc=11.0592MHz
TL0=0x7F // 定时器重装初值 fosc=11.0592MHz
//TH0 = 0xFD // 定时器重装初值 fosc=18.432MHz
//TL0 = 0x7F // 定时器重装初值 fosc=18.432MHz
}
void WByte(uchar input)
{
//发送启始位
uchar j=8
TR0=1
newTXD=(bit)0
WaitTF0()
//发送8位数据位
while(j--)
{
newTXD=(bit)(input&0x01) //先传低位
WaitTF0()
input=input>>1
}
//发送校验位(无)
//发送结束位
newTXD=(bit)1
WaitTF0()
TR0=0
}
void Sendata()
{
for(i=0i<sizeof(info)i++)//外层循环,遍历数组
{
WByte(info[i])
}
}
void main()
{
UartInit()
while(1)
{
Sendata()
}
}
##############################################################################
/***************************************************************
* 模拟接收程序,这个程序的作用从模拟串口接收数据,然后将这些数据发送到实际串口
*在单片机上模拟了一个串口,使用P3.2作为发送和接收端
*以P3.2模拟串口接收端,从模拟串口接收数据发至串口
***************************************************************/
#include<reg51.h>
#include<stdio.h>
#include<string.h>
typedef unsigned char uchar
//这里用来切换晶振频率,支持11.0592MHz和18.432MHz
//#define F18_432
#define F11_0592
uchar tmpbuf2[64]={0}
//用来作为模拟串口接收数据的缓存
struct
{
uchar recv :6 //tmpbuf2数组下标,用来将模拟串口接收到的数据存放到tmpbuf2中
uchar send :6 //tmpbuf2数组下标,用来将tmpbuf2中的数据发送到串口
}tmpbuf2_point={0,0}
sbit newRXD=P3^2 //模拟串口的接收端设为P3.2
void UartInit()
{
SCON=0x50 // SCON: serail mode 1, 8-bit UART
TMOD|=0x21 // TMOD: timer 1, mode 2, 8-bit reload,自动装载预置数(自动将TH1送到TL1)T0工作在方式1,十六位定时
PCON|=0x80 // SMOD=1
#ifdef F11_0592
TH1=0xE8 // Baud:2400 fosc=11.0592MHz 2400bps为从串口接收数据的速率
TL1=0xE8 // 计数器初始值,fosc=11.0592MHz 因为TH1一直往TL1送,所以这个初值的意义不大
TH0=0xFF // 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz
TL0=0xA0 // 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz
#endif
#ifdef F18_432
TH1=0xD8 // Baud:2400 fosc=18.432MHz 2400bps为从串口接收数据的速率
TL1=0xD8 // 计数器初始值,fosc=18.432MHz 因为TH1一直往TL1送,所以这个初值的意义不大
TH0=0xFF // 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18.432MHz
TL0=0x60 // 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18.432MHz
#endif
IE|=0x81 // 中断允许总控制位EA=1使能外部中断0
TF0=0
IT0=1 // 设置外部中断0为边沿触发方式
TR1=1 // 启动TIMER1,用于产生波特率
}
void WaitTF0(void)
{
while(!TF0)
TF0=0
#ifdef F11_0592
TH0=0xFF // 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
TL0=0xA0 // 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
#endif
#ifdef F18_432
TH0=0xFF
// 定时器重装初值 fosc=18.432MHz
TL0=0x60
// 定时器重装初值 fosc=18.432MHz
#endif
}
//接收一个字符
uchar RByte()
{
uchar Output=0
uchar i=8
TR0=1 //启动Timer0
#ifdef F11_0592
TH0=0xFF // 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
TL0=0xA0 // 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
#endif
#ifdef F18_432
TH0=0xFF // 定时器重装初值 fosc=18.432MHz
TL0=0x60 // 定时器重装初值 fosc=18.432MHz
#endif
TF0=0
WaitTF0()//等过起始位
//接收8位数据位
while(i--)
{
Output>>=1
if(newRXD)Output|=0x80 //先收低位
WaitTF0()//位间延时
}
TR0=0 //停止Timer0
return Output
}
//向COM1发送一个字符
void SendChar(uchar byteToSend)
{
SBUF=byteToSend
while(!TI)
TI=0
}
void main()
{
UartInit()
while(1)
{
if(tmpbuf2_point.recv!=tmpbuf2_point.send)//差值表示模拟串口接收数据缓存中还有多少个字节的数据未被处理(发送至串口)
{
SendChar(tmpbuf2[tmpbuf2_point.send++])
}
}
}
//外部中断0,说明模拟串口的起始位到来了
void Simulated_Serial_Start()interrupt 0
{
EX0=0 //屏蔽外部中断0
tmpbuf2[tmpbuf2_point.recv++]=RByte()//从模拟串口读取数据,存放到tmpbuf2数组中
IE0=0 //防止外部中断响应2次,防止外部中断函数执行2次
EX0=1 //打开外部中断0
}
51单片机超声波DIY
如下程序是在 STC 官方网站 提供的。应该很有用。////
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz
#include "reg51.h"
#include "intrins.h"
#define FOSC18432000L
#define BAUD9600
typedef unsigned char BYTE
typedef unsigned int WORD
#define URMD0 //0:使用定时器2作为波特率发生器
//1:使用定山烂纯时器1的模式0(16位自动重载模式)作为波特率发生器
//2:使用定时器1的模式2(8位自动重载模式)作为历搭波特率发生器
sfr T2H = 0xd6 //定时器2高8位
sfr T2L = 0xd7 //定时器2低8位
sfr AUXR = 0x8e //辅助寄存器
sfr ADC_CONTR = 0xBC //ADC控制寄存器
sfr ADC_RES = 0xBD //ADC高8位结果
sfr ADC_LOW2= 0xBE //ADC低2位结果
sfr P1ASF = 0x9D //P1口第2功能控制寄存器
#define ADC_POWER 0x80//ADC电源控制位
#define ADC_FLAG0x10//ADC完成标志
#define ADC_START 0x08//ADC起始控制位
#define ADC_SPEEDLL 0x00//540个时钟
#define ADC_SPEEDL 0x20//逗咐360个时钟
#define ADC_SPEEDH 0x40//180个时钟
#define ADC_SPEEDHH 0x60//90个时钟
void InitUart()
void InitADC()
void SendData(BYTE dat)
BYTE GetADCResult(BYTE ch)
void Delay(WORD n)
void ShowResult(BYTE ch)
void main()
{
InitUart()//初始化串口
InitADC() //初始化ADC
while (1)
{
ShowResult(0) //显示通道0
ShowResult(1) //显示通道1
ShowResult(2) //显示通道2
ShowResult(3) //显示通道3
ShowResult(4) //显示通道4
ShowResult(5) //显示通道5
ShowResult(6) //显示通道6
ShowResult(7) //显示通道7
}
}
/*----------------------------
发送ADC结果到PC
----------------------------*/
void ShowResult(BYTE ch)
{
SendData(ch) //显示通道号
SendData(GetADCResult(ch))//显示ADC高8位结果
//SendData(ADC_LOW2) //显示低2位结果
}
/*----------------------------
读取ADC结果
----------------------------*/
BYTE GetADCResult(BYTE ch)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START
_nop_() //等待4个NOP
_nop_()
_nop_()
_nop_()
while (!(ADC_CONTR &ADC_FLAG))//等待ADC转换完成
ADC_CONTR &= ~ADC_FLAG//Close ADC
return ADC_RES//返回ADC结果
}
/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{
SCON = 0x5a //设置串口为8位可变波特率
#if URMD == 0
T2L = 0xd8//设置波特率重装值
T2H = 0xff//115200 bps(65536-18432000/4/115200)
AUXR = 0x14 //T2为1T模式, 并启动定时器2
AUXR |= 0x01 //选择定时器2为串口1的波特率发生器
#elif URMD == 1
AUXR = 0x40 //定时器1为1T模式
TMOD = 0x00 //定时器1为模式0(16位自动重载)
TL1 = 0xd8//设置波特率重装值
TH1 = 0xff//115200 bps(65536-18432000/4/115200)
TR1 = 1 //定时器1开始启动
#else
TMOD = 0x20 //设置定时器1为8位自动重装载模式
AUXR = 0x40 //定时器1为1T模式
TH1 = TL1 = 0xfb //115200 bps(256 - 18432000/32/115200)
TR1 = 1
#endif
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
P1ASF = 0xff //设置P1口为AD口
ADC_RES = 0 //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL
Delay(2) //ADC上电并延时
}
/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
while (!TI) //等待前一个数据发送完成
TI = 0//清除发送标志
SBUF = dat//发送当前数据
}
/*----------------------------
软件延时
----------------------------*/
void Delay(WORD n)
{
WORD x
while (n--)
{
x = 5000
while (x--)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)