求AT89S52单片机程序

求AT89S52单片机程序,第1张

我这是C语言版 我自己编的,测试通过 其易懂

#include<at89x52h>

#include<intrinsh>

#define uchar unsigned char

#define uint unsigned int

sbit beep=P1^7;

bit sd,ds,dscz;

uchar count,sheding,dingshi;

uchar bdata sdyw; //可位寻址存储器设定

sbit sdyw_0=sdyw^0;

sbit sdyw_1=sdyw^1;

sbit sdyw_2=sdyw^2;

sbit sdyw_3=sdyw^3;

sbit sdyw_4=sdyw^4;

sbit sdyw_5=sdyw^5;

uchar bdata dsyw; //可位寻址存储器设定

sbit dsyw_0=dsyw^0;

sbit dsyw_1=dsyw^1;

sbit dsyw_2=dsyw^2;

sbit dsyw_3=dsyw^3;

sbit dsyw_4=dsyw^4;

sbit dsyw_5=dsyw^5;

uchar dismiaoshi,dismiao,disfen,disfenshi,disshi,disshishi; // 时钟显示用

uchar dsmiao,dsmiaoshi,dsdisfen,dsdisfenshi,dsdisshi,dsdisshishi ; // 定时显示用

delay(uint);//延时子函数声明

sbit rs=P1^0; sbit lcden=P1^2; sbit rw=P1^1;//与1602接口引脚

uchar table1[]="0123456789";

writecom(uchar com) //写指令子函数

{

P0=com;

rs=0;

lcden=0;delay(10);

lcden=1;delay(10);

lcden=0;

}

writedate(uchar date) //写数据子函数

{

P0=date;rs=1;

lcden=0;delay(10);

lcden=1;delay(10);

lcden=0;

}

void init() //初始化

{

writecom(0x38);delay(20); //子函数前面先写出来,下面才能掉用

writecom(0x0c);delay(20);

writecom(0x06);delay(20);

}

void main()

{

rw=0;//写允许

P2_4=0;//键盘用

init(); // 这里不能要“void”

EA=1;ET1=1;TMOD=0x10;

TH1=(65536-46200)/256;

TL1=(65536-46200)%256;

TR1=1;

writecom(0x84);delay(10);writedate(':');//这里不能用双引号

writecom(0x87);delay(10);writedate(':');

while(1)

{

if(ds==0) //若进入定时程序,这里不显,去显定时值,但时分秒数据在走

{writecom(0x89);delay(10); //计时写入1602程序

writedate(table1[dismiao]);

writecom(0x88);delay(10);

writedate(table1[dismiaoshi]);

writecom(0x86);delay(10);

writedate(table1[disfen]);

writecom(0x85);delay(10);

writedate(table1[disfenshi]);

writecom(0x83);delay(10);

writedate(table1[disshi]);

writecom(0x82);delay(10);

writedate(table1[disshishi]);

}

if(P2_3==0&P2_0==1)//定时判断

{ dingshi++;

delay(50000);

}

if(P2_0==0&P2_3==1) //设定判断

{

sheding++;

delay(50000);

}

if(sheding==3) //设定判断成功

{ sheding=0;

P1_7=0;EA=0;

delay(35530);P1_7=1;//

sd=1;

sdyw=1; //设定移位赋初值要在这里赋,若在if(ds==1) 里赋sdyw=1; 总是被执行,这里不要用sdyw_0=1;因为这样其他位不一定为0;

}

if(P2_0==1&sheding!=4) {sheding=0;} //若P20松开后不等于4,sheding要清0,

if(P2_3==1&dingshi!=3) {dingshi=0;} //若P23松开后不等于3,dingshi要清0,

if(dingshi==3) //定时判断成功

{dingshi=0;ds=1;P1_7=0;delay(30000); P1_7=1; dsyw=1; }// 定时标志置1,dsyw=0;dsyw_0=1; 很重要主要让移位有规律

if(ds==1)//进入定时程序

{

dscz=1;

if(P2_1==0) //定时移位

{

P1_7=0;

dsyw=_crol_(dsyw,1);

delay(20000); // 这里delay(20000);可以防抖

P1_7=1;

}

if(dsyw_4==1){dsyw=1;}//这里不要写dsyw_0=1;否则下次移位 dsyw_5=1;

dsmiao=0;dsmiaoshi=0;

if(P2_2==0&dsyw_0==1){dsdisfen++;if(dsdisfen==10){dsdisfen=0;}delay(20000);}

if(P2_2==0&dsyw_1==1){dsdisfenshi++;if(dsdisfenshi==6){dsdisfenshi=0;}delay(20000);}

if(P2_2==0&dsyw_2==1){dsdisshi++;if(dsdisshi==10){dsdisshi=0;}delay(20000);}

if(P2_2==0&dsyw_3==1){dsdisshishi++;if(dsdisshishi==3){dsdisshishi=0;}delay(20000);}

if(dsdisshishi==2&dsdisshi>3){dsdisshishi=0;dsdisshi=0;}

writecom(0x89);delay(10); //定时写入1602程序

writedate(table1[dsmiao]);

writecom(0x88);delay(10);

writedate(table1[dsmiaoshi]);

writecom(0x86);delay(10);

writedate(table1[dsdisfen]);

writecom(0x85);delay(10);

writedate(table1[dsdisfenshi]);

writecom(0x83);delay(10);

writedate(table1[dsdisshi]);

writecom(0x82);delay(10);

writedate(table1[dsdisshishi]);

if(P2_3==0)

{P1_7=0;

delay(5000);P1_7=1;ds=0;

}

}//定时退出

if(sd==1)//设定程序开始

{

if(P2_1==0) //设定移位

{

P1_7=0;

sdyw=_crol_(sdyw,1);

delay(20000) ; // 这里delay(20000);可以防抖

P1_7=1;

if(sdyw_4==1){sdyw=1;}//这里最好不要用sdyw_0=1;这样当sdyw_4=1时再移一位就成sdyw_0=1;sdyw_5也等于1

}

if(P2_2==0&sdyw_0==1){disfen++;if(disfen==10){disfen=0;}delay(20000);} //以下为设定用

if(P2_2==0&sdyw_1==1){disfenshi++;if(disfenshi==6){disfenshi=0;}delay(20000);}

if(P2_2==0&sdyw_2==1){disshi++;if(disshi==10){disshi=0;}delay(20000);}

if(P2_2==0&sdyw_3==1){disshishi++;if(disshishi==3){disshishi=0;}delay(20000);}

if(disshishi==2&disshi==4){disshishi=0;disshi=0;}

writecom(0x89);delay(10); //设定写入1602

writedate(table1[dismiao]);

writecom(0x88);delay(10);

writedate(table1[dismiaoshi]);

writecom(0x86);delay(10);

writedate(table1[disfen]);

writecom(0x85);delay(10);

writedate(table1[disfenshi]);

writecom(0x83);delay(10);

writedate(table1[disshi]);

writecom(0x82);delay(10);

writedate(table1[disshishi]); //设定写入程序到此

if(P2_0==0) //设定好按P00退出

{

EA=1;sd=0;

P1_7=0;

delay(5000);P1_7=1;

}

} //退出设定程序

if(dscz==1&ds==0)

{

if(disshi==dsdisshi&disshishi==dsdisshishi&disfen==dsdisfen&disfenshi==dsdisfenshi) //定时时间到

{P1_7=!P1_7;delay(30000);P1_7=!P1_7;delay(30000);}

}

}

}

void time() interrupt 3 //中断服务

{

TH1=(65536-46050)/256;

TL1=(65536-46050)%256;

count++;

if(count==20) //时分秒计算,放在这里计时准,直接中断控制,在while(1)里计时受其他程序影响

{

count=0;

dismiao++;

if(dismiao==10){dismiaoshi++;dismiao=0;} //dismiao,disfen,disshi,等这些数据在退出while(1)函数后再回来都会变为0,

if(dismiaoshi==6){dismiaoshi=0;disfen++;}

if(disfen==10){disfen=0;disfenshi++;}

if(disfenshi==6){disfenshi=0;disshi++;}

if(disshi==10){disshi=0;disshishi++;}

if(disshishi==2&disshi==4){disshishi=0;disshi=0;}

} //if(count==19)循环到此

}

delay(uint x )//延时子函数

{

uint a;

for(a=x;a>0;a--);

}

AT89S52下载协议是SPI总线格式的4根线

用一个USPASP就可以下载程序了

现在淘宝上大把

AT89S52也支持传统高压编程,也就是并行编程

这个要那个大型的编程器,不怎么方便。

在做单片机的程序,由于串口不够,需要用IO口来模拟出一个串口。经过若干曲折并参考了一些现有的资料,基本上完成了。现在将完整的测试程序,以及其中一些需要总结的部分贴出来。

程序硬件平台:110592M晶振,

/

在单片机上模拟了一个串口,使用P21作为发送端

把单片机中存放的数据通过P21作为串口TXD发送出去

/

#include <reg51h>

#include <stdioh>

#include <stringh>

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;//模拟串口的发送端设为P21

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=110592MHz

TL0 = 0x7F; // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=110592MHz

// TH0 = 0xFD; // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18432MHz

// TL0 = 0x7F; // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18432MHz

}

void WaitTF0(void)

{

while(!TF0);

TF0=0;

TH0=0xFE; // 定时器重装初值 fosc=110592MHz

TL0=0x7F; // 定时器重装初值 fosc=110592MHz

// TH0 = 0xFD; // 定时器重装初值 fosc=18432MHz

// TL0 = 0x7F; // 定时器重装初值 fosc=18432MHz

}

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=0;i<sizeof(info);i++)//外层循环,遍历数组

{

WByte(info[i]);

}

}

void main()

{

UartInit();

while(1)

{

Sendata();

}

}

##############################################################################

/

模拟接收程序,这个程序的作用从模拟串口接收数据,然后将这些数据发送到实际串口

在单片机上模拟了一个串口,使用P32作为发送和接收端

以P32模拟串口接收端,从模拟串口接收数据发至串口

/

#include<reg51h>

#include<stdioh>

#include<stringh>

typedef unsigned char uchar ;

//这里用来切换晶振频率,支持110592MHz和18432MHz

//#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 ;//模拟串口的接收端设为P32

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=110592MHz 2400bps为从串口接收数据的速率

TL1=0xE8 ;// 计数器初始值,fosc=110592MHz 因为TH1一直往TL1送,所以这个初值的意义不大

TH0=0xFF ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=110592MHz

TL0=0xA0 ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=110592MHz

#endif

#ifdef F18_432

TH1=0xD8 ; // Baud:2400 fosc=18432MHz 2400bps为从串口接收数据的速率

TL1=0xD8 ; // 计数器初始值,fosc=18432MHz 因为TH1一直往TL1送,所以这个初值的意义不大

TH0=0xFF ;// 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18432MHz

TL0=0x60 ;// 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18432MHz

#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=110592MHz

TL0=0xA0 ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=110592MHz

#endif

#ifdef F18_432

TH0=0xFF ;

// 定时器重装初值 fosc=18432MHz

TL0=0x60 ;

// 定时器重装初值 fosc=18432MHz

#endif

}

//接收一个字符

uchar RByte()

{

uchar Output=0 ;

uchar i=8 ;

TR0=1 ; //启动Timer0

#ifdef F11_0592

TH0=0xFF ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=110592MHz

TL0=0xA0 ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=110592MHz

#endif

#ifdef F18_432

TH0=0xFF ;// 定时器重装初值 fosc=18432MHz

TL0=0x60 ;// 定时器重装初值 fosc=18432MHz

#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_pointrecv!=tmpbuf2_pointsend)//差值表示模拟串口接收数据缓存中还有多少个字节的数据未被处理(发送至串口)

{

SendChar(tmpbuf2[tmpbuf2_pointsend++]);

}

}

}

//外部中断0,说明模拟串口的起始位到来了

void Simulated_Serial_Start()interrupt 0

{

EX0=0 ; //屏蔽外部中断0

tmpbuf2[tmpbuf2_pointrecv++]=RByte(); //从模拟串口读取数据,存放到tmpbuf2数组中

IE0=0 ; //防止外部中断响应2次,防止外部中断函数执行2次

EX0=1 ; //打开外部中断0

}

51单片机超声波DIY

at89S52 在线烧程序要用P15,P16,P17,RST。

这只留出几个脚也没有用啊,要用烧录线,现在只能买USB转ISP的烧录线,而且要向店家说明,是给AT89S52烧录程序的,还要向店家要烧录软件。

现在,给AT89S52烧录程序是很麻烦的事,不如用STC89C52,用USB转TTL模块就搞定了,这种模块,网上可以买到,非常多,也好买。

#include<reg52h>

sbit led = P1^0;

void mian()

{

led = 0;//如果是LED阳极接在单片机上,则是--> led = 1;

while(1);

}

你的学习板是无法实现对AT89S52的烧录的,因为AT89S52不具备“自编程”的功能。

详细说明一下:

AT89S52的烧录模式属于ISP,通俗的说是其它电路直接 *** 作单片机的3根专用的端口完成烧录,属于硬件烧录模式;

而你说用的STC89C52学习板的烧录模式属于IAP,通俗的讲就是单片机通过学习板的串口,接收到需要烧录的程序代码,然后进行“自编程”,姑且叫它软件模式,换句话说只有具备“自编程”性能的单片机才“可能”在你的学习板上完成烧录。

(关于ISP和IAP,可以看一下下面这个连接,里面简单说明了下载烧录的原理,STC的单片机与SST的类似,应该对你有帮助的:>

#include<reg51h>

#define uchar unsigned char

#define LCM_Data P0

#define Busy 0x80 //用于检测LCM状态字中的Busy

sbit RW=P2^1; //定义引脚

sbit RS=P2^0;

sbit EN=P2^2;

sbit int1=P3^3;//定义管脚功能

//sbit cs=P3^2; //使能端

sbit wr=P3^6; //写端口

sbit rd=P3^7; //读端口

unsigned char disp[4]={0,0,0,0};

unsigned char _adc;

void dataproc(unsigned char);

void display(unsigned);

void delay1ms(char);

unsigned char adc0804();

unsigned char v='v';

unsigned char adc0804( ) //读AD0804子程序

{

unsigned char addata,i;

rd=1;

wr=1;

int1=1; //读ADC0804 前准备

P1=0xff; //P1全部置一准备

//cs=0;

wr=0;

wr=1; //启动ADC0804开始测电压

while(int1==1); //查询等待A/D转换完毕产生的INT(低电平有效)信号

rd=0; //开始读转换后数据

i=i; i="i"; //无意义语句,用于延时等待ADC0804 读数完毕

addata=P1; //读出的数据赋与addate

//while(1);

rd=1;

//cs=1; //读数完毕

return(addata); //返回最后读出的数据

}

void dataproc(unsigned char data_in)

{ int results;

results=data_in196;

disp[3]=(results/10000)+0x30;

disp[2]=((results/1000)%10)+0x30;

disp[1]=((results/100)%10)+0x30;

disp[0]=((results/10)%10)+0x30;

}

/lcd1602程序/

void delay1ms(unsigned int ms)//延时1毫秒(不够精确的 ,内部函数)

{unsigned int i,j;

for(i=0;i<ms;i++)

for(j=0;j<100;j++);

}

void wr_com(unsigned char com)//写指令// (内部函数)

{ delay1ms(1);

RS=0;

RW=0;

P0=com;

EN=1;

delay1ms(1);

EN=0;

}

void wr_dat(unsigned char dat)//写数据// (内部函数)

{ delay1ms(1);;

RS=1;

RW=0;

EN=0;

P0=dat;

delay1ms(1);

EN=1;

delay1ms(1);

EN=0;

}

void lcd_init()//初始化设置// (外部调用)

{delay1ms(15);

wr_com(0x38);delay1ms(5);

wr_com(0x08);delay1ms(5);

wr_com(0x01);delay1ms(5);

wr_com(0x06);delay1ms(5);

wr_com(0x0c);delay1ms(5);

}

void main()//主函数

{ while(1)

{

_adc= adc0804( ) ;

dataproc(_adc);

lcd_init();

wr_com(0x80);

wr_dat(disp[3]);

wr_com(0x81);

wr_dat(0x2E);

wr_com(0x82);

wr_dat(disp[2]);

wr_com(0x83);

wr_dat(disp[1]);

wr_com(0x84);

wr_dat(disp[0]);

wr_com(0x85);

wr_dat(v);

//while(1);

}

这是我的程序 我用的0804 但其实都是一样的 呵呵

以上就是关于求AT89S52单片机程序全部的内容,包括:求AT89S52单片机程序、AT89S52单片机怎么下载程序、AT89S52单片机并行转串行c语言程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: https://outofmemory.cn/zz/9291474.html

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

发表评论

登录后才能评论

评论列表(0条)

保存