搜档网
当前位置:搜档网 › 单片机读取130218B021602

单片机读取130218B021602

单片机读取130218B021602
单片机读取130218B021602

以下为AVR系列单片机之ATMAGE128单片机写的程序,可以实现读取DS1302/18B02数据并在LCD1602显示,代码简单,易懂,给想想学1302/18C02/1602的朋友分一下,关健之处在于本程备注清晰,如果想学的朋友可以和小弟联系,一块学习!

/********************************************************

项目名称: 读取DS18B20温度/DS1302时间,通过1602液晶显示。

说明:

CPU型号: Atmage128A

主频: 12MHz

日期:2013/08/20

联系方法: ****************************

********************************************************/

#include

#include

///DS18B20宏定义

#define DE0 DDRE &= 0xbf //设置输入

#define DE1 DDRE |= 0x40 //设置输出

#define E0 PORTE &= 0xbf //置低电平

#define E1 PORTE |= 0x40 //置高电平

#define PIN PINE & 0x40 //读了电平

//LCD1602宏定义

#define EN_1 PORTB |= 1<

#define EN_0 PORTB &= ~(1<

//LCD读写控制引脚

#define RW_1 PORTB |= 1<

#define RW_0 PORTB &= ~(1<

//LCD指令或数据选择引脚

#define RS_1 PORTB |= 1<

#define RS_0 PORTB &= ~(1<

#define maichong EN_1,delay_ms(1),EN_0

//////////////////////////////////////////////////////////////////

#define ds1302_rst1 PORTE |= 1<

#define ds1302_rst0 PORTE &= ~(1<

#define ds1302_io_DDR1 DDRE |= 1<

#define set_ds1302_io PORTE |= 1<

#define clr_ds1302_io PORTE &= ~(1<

#define clr_ds1302_io_DDR0 DDRE &= ~(1<

#define in_ds1302_io PINE & (1<

#define set_ds1302_sclk_DDR1 DDRE|=1<

#define set_ds1302_sclk PORTE|=1<

#define clr_ds1302_sclk PORTE &=~(1<

#define miao 0x80 //秒数据地址

#define fen 0x82 //分数据地址

#define shi 0x84 //时数据地址

#define ri 0x86 //日数据地址

#define yue 0x88 //月数据地址

#define zhou 0x8a //星期数据地址

#define nian 0x8c //年数据地址

#define ds1302_control_add 0x8e //控制数据地址

#define ds1302_charger_add 0x90

#define ds1302_clkburst_add 0xbe

/****************************/

unsigned char Table[]={0xc0,0xf9,0xa4,0xb0,0x99,

0x92,0x82,0xf8,0x80,0x90,0xff};

unsigned char duanma[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; unsigned char DS18B20_temperature[5];

unsigned char s[32];

unsigned char timer[8]; //时钟数据

unsigned int temperature;

void delay_us(unsigned char i)

{

for(;i;i--);

}

void delay_ms(unsigned int i) //在1M时钟下为i ms

{

unsigned char j;

for(;i;i--)

for(j=220;j;j--);

}

/*************************************

* DS1302操作函数组*

*************************************/

//写入1302数据函数:

//入口:add为写入地址码,data为写入数据

//返回:无

void ds1302_write(unsigned char add,unsigned char data)

{

unsigned char i=0;

ds1302_io_DDR1; //配置IO为输出

delay_us(20);

ds1302_rst0; //清复位,停止所有操作

delay_us(20);

clr_ds1302_sclk; //清时钟,准备操作

delay_us(20);

ds1302_rst1; //置复位,开始操作

delay_us(20);

for(i = 8; i > 0; i--) //此循环写入控制码

{

if(add & 0x01)

set_ds1302_io; //当前位为1,置数据位

else

clr_ds1302_io; //当前位为0,清数据位

delay_us(20);

set_ds1302_sclk; //产生时钟脉冲,写入数据

delay_us(1);

clr_ds1302_sclk;

delay_us(20);

add >>= 1; //移位,准备写入下1位}

for(i=8;i>0;i--) //此循环写入数据码

{

if(data & 0x01)

set_ds1302_io;

else

clr_ds1302_io;

delay_us(20);

set_ds1302_sclk;

delay_us(20);

clr_ds1302_sclk;

delay_us(20);

data>>=1;

}

ds1302_rst0;

delay_us(20);

clr_ds1302_io_DDR0; //清输出状态

delay_us(20);

}

//从1302中读出数据:

//入口:add为读数据所在地址

//返回:读出的数据data

unsigned char ds1302_read(unsigned char add)

{

unsigned char data = 0;

unsigned char i = 0;

add += 1; //读标志

ds1302_io_DDR1; //端口输出

delay_us(20);

ds1302_rst0;; //清复位

delay_us(20);

clr_ds1302_sclk; //清时钟

delay_us(20);

ds1302_rst1; //置复位

delay_us(20);

for(i = 8; i > 0; i--) //此循环写入地址码

{

if(add&0x01) {set_ds1302_io;}

else {clr_ds1302_io;}

delay_us(20);

set_ds1302_sclk;

delay_us(20);

clr_ds1302_sclk;

delay_us(20);

add >>= 1;

}

clr_ds1302_io_DDR0; //端口输入

delay_us(20);

for(i = 8; i > 0; i--) //此循环读出1302的数据

{

data>>=1;

if(in_ds1302_io)

{data|=0x80;}

delay_us(20);

set_ds1302_sclk;

delay_us(20);

clr_ds1302_sclk;

delay_us(20);

}

ds1302_rst0;

delay_us(20);

return(data);

}

//检查1302状态

// unsigned char check_ds1302(void)

// {

// ds1302_write(ds1302_control_add,0x80);

// if(ds1302_read(ds1302_control_add) == 0x80)

// return 1;

// return 0;

// }

//向1302中写入时钟数据

void ds1302_write_time(void)

{

ds1302_write(ds1302_control_add,0x00); //关闭写保护

ds1302_write(miao,0x80); //暂停

ds1302_write(ds1302_charger_add,0xa9); //涓流充电

ds1302_write(nian,timer[0]); //年

ds1302_write(yue, timer[1]); //月

ds1302_write(ri, timer[2]); //日

ds1302_write(zhou,timer[3]); //周

ds1302_write(shi, timer[4]); //时

ds1302_write(fen, timer[5]); //分

ds1302_write(miao,timer[6]); //秒

ds1302_write(ds1302_control_add,0x80); //打开写保护}

void ds_1302_read_time(void) //从1302中读出当前时钟

{

timer[0] = ds1302_read(nian); //读年

timer[1] = ds1302_read(yue); //读月

timer[2] = ds1302_read(ri); //读日

timer[3] = ds1302_read(zhou); //读周

timer[4] = ds1302_read(shi); //读时

timer[5] = ds1302_read(fen); //读分

timer[6] = ds1302_read(miao); //读秒

s[12] = ((timer[0] & 0xf0)>>4) + 0x30; //年转换

s[11] = (timer[0] & 0x0f) + 0x30; //年转换

s[10] = ((timer[1] & 0xf0)>>4) + 0x30; //月转换

s[9] = (timer[1] & 0x0f) + 0x30; //月转换

s[8] = ((timer[2] & 0xf0)>>4) + 0x30; //日转换

s[7] = (timer[2] & 0x0f) + 0x30; //日转换

s[6] = (timer[3] & 0x0f) + 0x30; //周转换

s[5] = ((timer[4] & 0xf0)>>4) + 0x30; //时转换

s[4] = (timer[4] & 0x0F) + 0x30; //时转换s[3] = ((timer[5] & 0xF0)>>4) + 0x30; //分转换

s[2] = (timer[5] & 0x0F) + 0x30; //分转换s[1] = ((timer[6] & 0xF0)>>4) + 0x30; //秒转换

s[0] = ((timer[6] & 0x0F) + 0x30); //秒转换}

DS1302_time_init()

{

timer[0] = 0X13; //写年

timer[1] = 0X09; //写月

timer[2] = 0X04; //写日

timer[3] = 0X03; //写周

timer[4] = 0X01; //写时

timer[5] = 0X41; //写分

timer[6] = 0X50; //写秒

}

/**************************************

* 扫描显示函数组*

**************************************/

//延时函数1

//////////////////////////////////////////////////////////////////

void MCU_init(void) //单片机初初化程序

{

DDRE = 0xFF;

PORTE = 0xff;

DDRA = 0XFF; //LED IO口设为输出

PORTA = 0XFF;

DDRB &= 0xEf;

EN_1;

RW_1;

RS_1;

}

void LCD_init(void) //LCD1602液晶初始化

{

delay_ms(1);

DDRA = 0xFF;

DDRB |= 0xe0; //端口B5、6、7、置为输出

write_onechar(0x38,0); //高置显示格式为16*2个字符5*7点阵

write_onechar(0x01,0); //01清屏指行令

write_onechar(0x0F,0); //显示关闭0000 1DCB D显示开关,C光标显示开关,B 光标闪烁开关*/

write_onechar(0x06,0); //显示光标移动设置*/

delay_ms(1);

write_onechar(0x0C,0); //显示开机光标设置*/

}

//////////////////////////////////

void LCD_ready(void) /*功能描述:判断LCD忙标志*/

{

DDRA = 0X00; //D7设为输判断LCD忙标志//1为忙入,准备0为空闲

RS_0;

RW_1; //读

EN_1;

delay_ms(2);

while(PINC & 0X80);

EN_0;

RS_1;

DDRA=0xFF;

}

void LCD_xieshuju(unsigned char X,unsigned char Y,unsigned char *string)//X坐标位置,Y坐标位置,*string要写的内容

{

unsigned char address;

if (Y == 0) address = 0x80 + X; //第一行X列

else address = 0xc0 + X; //第二行X列

write_onechar( address, 0 );

while (*string)

{

write_onechar(0,*string );

string ++; //指向下一显示字符地址

}

}

void write_onechar(unsigned char COMM,unsigned char DA T)

{

LCD_ready(); //等待LCD空闲

RW_0; //写

if(COMM == 0) //写数据

{

RS_1; //RS高电平向LCD写数据

PORTA=DAT;

}

else //写命令

{

RS_0;

PORTA=COMM;

}

maichong;

delay_ms(1);

RW_1;

RS_1;

}

////////////////////////////DS18B20复位函数

DS18B20_reset(void)

{

unsigned char i;

DE1;

E0;

delay_us(500); /*延时500uS(480-960)*/

E1;

DE0;

delay_us(500); /*延时500uS(保持>480uS)*/

}

DS18B20_read()

{

unsigned char i;

unsigned char value = 0;

for (i = 8; i != 0; i--)

{

value >>= 1;

DE1;

E0;

asm("nop"); /*延时4uS*/

asm("nop");

asm("nop");

asm("nop");

E1;

DE0;

delay_us(1); /*延时10uS*/

if (PIN)

value |= 0x80;

delay_us(50); /*延时60uS*/

}

return(value);

}

void DS18B20_write(unsigned char value)

{

unsigned char i;

for (i = 8; i != 0; i--)

{

DE1;

E0;

asm("nop");asm("nop");asm("nop");asm("nop"); /*延时4uS*/

if (value & 0x01) E1;

delay_us(70); /*延时80uS*/

E1; /*位结束*/

value >>= 1;

}

}

unsigned int DS18B20_read_temperature(void)

{

unsigned int i;

unsigned char buf[9];

unsigned char DS18B20_temperature[5];

DS18B20_reset();

DS18B20_write(0xCC); /*勿略地址*/

DS18B20_write(0xBE); /*读取温度*/

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

{

buf[i] = DS18B20_read();

}

i = buf[1];

i <<= 8;

i |= buf[0];

return i;

}

DS18B20_zhuanhuan()

{

DS18B20_reset(); //

DS18B20_write(0xCC); //勿略地址

DS18B20_write(0x44); //启动转换

temperature = DS18B20_read_temperature();

temperature = (temperature*100) >> 4;

DS18B20_temperature[4] =temperature/10000, temperature = temperature%10000;

DS18B20_temperature[3] =temperature/1000, temperature = temperature%1000;

DS18B20_temperature[2] =temperature/100, temperature = temperature%100;

DS18B20_temperature[1] =temperature/10, temperature = temperature%10;

DS18B20_temperature[0] =temperature%10;

}

void main(void)

{

unsigned int m;

unsigned long i,i1;

unsigned char start1[]={" 2013/08/31 6 "};

unsigned char start2[]={" I LOVE YOU "};

MCU_init;

LCD_init();

DS18B20_reset(); //复位D18B20

write_onechar(0X01,0);

LCD_xieshuju(0,1,start1);

delay_ms(5000);

LCD_xieshuju(0,1,start2);

delay_ms(100000);

DS1302_time_init();

//ds1302_write_time(); //写入初始时钟

while(1)

{

DS18B20_zhuanhuan(); //启动转换

ds_1302_read_time(); //读出当前时钟

write_onechar(0x80,0); //首地址

write_onechar(0,0x32); //01----2

write_onechar(0,0x30); //02----0

write_onechar(0,s[12]); //03----1

write_onechar(0,s[11]); //04----3

write_onechar(0,0x2F); //05----/

write_onechar(0,s[10]); //06----0

write_onechar(0,s[9]); //07----8

write_onechar(0,0x2F); //08----/

write_onechar(0,s[8]); //09----3

write_onechar(0,s[7]); //09----1

write_onechar(0,0X20); //10

write_onechar(0,s[6]); //11----5

write_onechar(0,0x20);

write_onechar(0,0x36);

write_onechar(0,0x38);

write_onechar(0xC0,0);

write_onechar(0,s[5]); //12

write_onechar(0,s[4]); //13

write_onechar(0,0X3A); //14

write_onechar(0,s[3]); //15

write_onechar(0,s[2]); //16

write_onechar(0,0X3A); //读出当前时钟

write_onechar(0,s[1]); //读出当前时钟

write_onechar(0,s[0]); //读出当前时钟

if(DS18B20_temperature[4] == 0) write_onechar(0,0x20);

else write_onechar(0,DS18B20_temperature[4]+0x30);

write_onechar(0,DS18B20_temperature[3]+0x30);

write_onechar(0,DS18B20_temperature[2]+0x30);

write_onechar(0,0X2E);

write_onechar(0,DS18B20_temperature[1]+0x30);

write_onechar(0,DS18B20_temperature[0]+0x30);

write_onechar(0,0xdf);

write_onechar(0,0x43);

write_onechar(0X80,0);

}

}

单片机EEPROM的使用函数

/******************************************************************** 这是EEROM.h文件 ********************************************************************/ #ifndef _EEPROMus_h //对EEROM进行操作 #define _EEPROMus_h #include #include extern void EEw(unsigned int m,unsigned int,unsigned char w); //将第m扇区的第n个存储空间数据改成w extern void EEr(unsigned int m,unsigned int n,unsigned char *r); //将第m扇区的第n个存储空间数据读到r extern void EEe(unsigned int m); //删除第m扇区内的内容 extern void EEwa(unsigned int m,unsigned int n,unsigned char w[]); //在m扇区,从0x00写到第n个,写数组w里的数 extern void EEra(unsigned int m,unsigned int n,unsigned char r[]); //在m扇区,从0x00读到第n个,读到数组r里 #endif /******************************************************************** 这是EEPROM.c文件 ********************************************************************/ /******************************************************************** IAP_CONTR: B7: 0:禁止IAP 1:允许IAP B6和B5配合让程序从AP区和ISP监控区复位及程序的开始 B4:当IAP_TRIG触发的5a/a5失败,则为1,且由软件清零 B3:/ B2B1B0:设置CPU等待时间 IAP_TRIG: 每次发送命令后要用此寄存器发送5a,然后a5后,命令生效 IAP_CMD: 对IAP进行命令输入: 0x00:无操作 0x01:读 0x02:写

51单片机常用子程序汇总

目录 1、通过串口连续发送n个字节的数据 /*************************************************************** 模块功能:通过串口连续发送n个字节的数据 参数说明: s:待发送数据的首地址 n:要发送数据的字节数 ***************************************************************/ void SendD(unsigned char *s,unsigned char n) { unsigned char unX; if(n>0) { ES=0; // 关闭串口中断 for(unX=0;unX #include #define Nop() _nop_() //空指令

sbit SDA=P1^3; sbit SCL=P1^2; bit ACK; void Start_I2c() { SDA=1; Nop(); SCL=1; Nop(); Nop(); Nop(); Nop(); Nop(); SDA=0; Nop(); Nop(); Nop(); Nop(); Nop(); SCL=0; //钳住I2C总线,准备发送或接受数据Nop(); Nop(); } (2)结束总线函数 /*************************************************************** 模块功能:发送I2C总线结束条件 ***************************************************************/ void Stop_I2c() { SDA=0; Nop(); SCL=1; Nop(); Nop(); Nop(); Nop(); Nop(); SDA=1; Nop(); Nop(); Nop(); Nop();

单片机中断程序大全

单片机中断程序大全公司内部编号:(GOOD-TMMT-MMUT-UUPTY-UUYY-DTTI-

//实例42:用定时器T0查询方式P2口8位控制L E D闪烁#include // 包含51单片机寄存器定义的头文件void main(void) { // EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x01; //使用定时器T0的模式1 TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 TR0=1; //启动定时器T0 TF0=0; P2=0xff; while(1)//无限循环等待查询 { while(TF0==0) ; TF0=0; P2=~P2; TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 //实例43:用定时器T1查询方式控制单片机发出1KHz音频

#include // 包含51单片机寄存器定义的头文件sbit sound=P3^7; //将sound位定义为P3.7引脚 void main(void) {// EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x10; //使用定时器T1的模式1 TH1=(65536-921)/256; //定时器T1的高8位赋初值 TL1=(65536-921)%256; //定时器T1的高8位赋初值 TR1=1; //启动定时器T1 TF1=0; while(1)//无限循环等待查询 { while(TF1==0); TF1=0; sound=~sound; //将P3.7引脚输出电平取反 TH1=(65536-921)/256; //定时器T0的高8位赋初值 TL1=(65536-921)%256; //定时器T0的高8位赋初值 } } //实例44:将计数器T0计数的结果送P1口8位LED显示 #include // 包含51单片机寄存器定义的头文件sbit S=P3^4; //将S位定义为P3.4引脚

基于51单片机的USB键盘设计与实现

三江学院 本科生毕业设计(论文)题目基于51单片机的USB键盘设计与实现高职院院(系)电气工程及其自动化专业 学生姓名梁邱一学号 G105071013 指导教师孙传峰职称讲师 指导教师工作单位三江学院 起讫日期 2013年12月10日至2014年4月12日

摘要 随着计算机技术的不断更新和多媒体技术的快速发展,传统的计算机外设接口因为存在许多缺点已经不能适应计算机的发展需要。比起传统的AT,PS/2,串口,通用串行总线USB,具有速度快,使用方便灵活,易于扩展,支持即插即用,成本低廉等一系列优点,得到了广泛的应用。 本论文阐述了51系列单片机和USB的相关内容,详细介绍了系统的一些功能设计,包括硬件设计和软件设计。在程序调试期间用简单的串口通信电路,通过串口调试助手掌握了USB指令的传输过程,这对整个方案的设计起到了很大的指导作用。论文以单片机最小系统配合模拟键盘组成的USB键盘硬件系统,通过对D12芯片的学习与探索,在其基本命令接口的支持下,结合硬件进行相应的固件程序设计,使其在USB协议下,实现USB模块与PC的数据通信,完成USB键盘的功能模拟。 总结论文研究工作有阐述USB总线的原理、对本设计的系统要求作出了分析、根据要求选定元件和具体编程方案、针对系统所要实现的功能对相关芯片作了详细介绍以及在硬件部分设计了原理图。 关键词:USB;D12;PC

Abstract With the rapid development of computer technology and multimedia technology constantly updated, traditional computer peripheral interface because there are many shortcomings have been unable to meet the development needs of the https://www.sodocs.net/doc/0115841180.html,pared to traditional AT, PS / 2, serial, Universal Serial Bus USB, with fast, flexible and easy to use, easy to expand, support Plug and Play, a series of advantages, such as low cost, has been widely used. This paper describes the 51 series and USB related content, detailing some of the features of the system design, including hardware and software design.During debugging a simple serial communication circuit, through the serial port debugging assistant master USB transfer instructions, which designed the entire program has played a significant role in guiding.Thesis smallest single-chip system consisting of analog keyboard with a USB keyboard hardware system, by learning and exploration D12 chips, with the support of its basic command interface, in conjunction with the corresponding hardware firmware design, making it in the USB protocol, USB module data communication with the PC, the USB keyboard to complete the functional simulation. This paper summarizes research work has elaborated the principle of the USB bus, the system is designed to require the analysis, components and solutions based on the specific requirements of the selected programming for the system to achieve the function of the relevant chips are described in detail in the hardware part of the design as well as the principle of Figure. Keywords:USB;D12;PC

(完整版)单片机知识点总结

单片机考点总结 1.单片机由CPU、存储器及各种I/O接口三部分组成。 2.单片机即单片微型计算机,又可称为微控制器和嵌入式控制器。 3.MCS-51系列单片机为8位单片机,共40个引脚,MCS-51基本类型有8031、8051 和8751. (1)I/O引脚 (2)8031、8051和8751的区别: 8031片内无程序存储器、8051片内有4KB程序存储器ROM、8751片内有4KB程序存储器EPROM。 (3)

4.MCS-51单片机共有16位地址总线,P2口作为高8位地址输出口,P0口可分时复用 为低8位地址输出口和数据口。MCS-51单片机片外可扩展存储最大容量为216=64KB,地址范围为0000H—FFFFH。(1.以P0口作为低8位地址/数据总线;2. 以P2口作为高8位地址线) 5.MCS-51片内有128字节数据存储器(RAM),21个特殊功能寄存器(SFR)。(1)MCS-51片内有128字节数据存储器(RAM),字节地址为00H—7FH; 00H—1FH: 工作寄存器区; 00H—1FH: 可位寻址区; 00H—1FH: 用户RAM区。 (2)21个特殊功能寄存器(SFR)(21页—23页);

(3)当MCS-51上电复位后,片内各寄存器的状态,见34页表2-6。 PC=0000H, DPTR=0000H, Acc=00H, PSW=00H, B=00H, SP=07H, TMOD=00H, TCON=00H, TH0=00H, TL0=00H, TH1=00H, TL1=00H, SCON=00H, P0~P3=FFH 6. 程序计数器PC:存放着下一条要执行指令在程序存储器中的地址,即当前PC值或现行值。程序计数器PC是16位寄存器,没有地址,不是SFR. 7. PC与DPTR的区别:PC和DPTR都用于提供地址,其中PC为访问程序存储器提供地址,而DPTR为访问数据存储器提供地址。 8. MCS-51内部有2个16位定时/计数器T0、T1,1个16位数据指针寄存器DPTR,其中MOVE DPTR, #data16 是唯一的16位数据传送指令,用来设置地址指针DPTR。(46页) 定时/计数器T0和T1各由2个独立的8位寄存器组成,共有4个独立寄存器:TH1、TL1、TH0、TL0,可以分别对对这4个寄存器进行字节寻址,但不能吧T0或T1当作1个16位寄存器来寻址。即:MOV T0,#data16 ;MOV T1,#data16 都是错的,MOV TH0,#data;MOV TL0,,#data是正确的。 9.程序状态字寄存器PSW(16页) (1)PSW的格式: D7 D6 D5 D4 D3 D2 D1 D0 PSW D0H (2)PSW寄存器中各位的含义; Cy:进位标志位,也可以写为C。 Ac:辅助进位标志位。

单片机大汇总

1、简述时钟周期、机器周期、指令周期的概念及相互关系。 答:时钟周期是输入微处理器的时钟信号的周期。机器周期是机器完成一个基本动作的时间。在MCS-51系列单片机中,一个机器周期由12个时钟周期组成。指令周期是指执行一条指令所需的时间,由一个到数个机器周期组成。 2、MCS-51外扩的程序存储器和数据存储器,共用16位地址线和8位数据线,可以有相同的地址空间,为什么两个存储空间不会发生冲突? 答:因为51单片机访问片外程序存储器和数据存储器是通过不同的控制信号进行的,访问片外程序存储器使用PSEN信号,访问片外数据存储器使用WR和RD信号,因此它们有相同的地址空间也不会冲突。 3、写出C51的中断程序入口地址。 答:外部中断0 0003H;定时中断0 000BH;外部中断1 0013H;定时中断1 000BH;串行口中断 0023H 4、计算右图中使LED正常工作的限流电阻R的阻值,写出计算过程。 答:R=(VCC-VF-VCES)/IF 、VCC=5V,VF=1.8V(1.2~2.5V),VCES=0.2V(0.1~0.2V),IF=15mA(10~20mA)、R=200Ω 5、定义如下变量 (1)、内部RAM直接寻址区无符号字符变量i;(1)unsigned char data i; (2)、外部64K RAM的有符号整形变量x;(2)char int xdata x;

6、单片机系统中的定时和计数功能有何区别?分别适用于什么场合? 答:定时和计数的区别在于时钟来源不同,当使用内部时钟时,时钟是确定的,此时,定时器工作于定时方式;当使用外部时钟时,时钟是不确定的,此时,定时器工作于计数方式。 定时主要用来产生定时中断,实现定时采样输入信号,定时扫描键盘等; 计数主要用来对外部输入时钟累加统计或测量外部输入时钟的参数等。 7、单片机通过I/O引脚直接连接矩阵式按键时,有几种识别按键的方法,请分别说明详细过程? 答:逐行扫描法:列(行)作为输出,行(列)作为输入,先把第一列(行)置低电平,其余各列(行)为高电平,读行(列)线的状态,如果某行(列)线电平为低,可确定此行列交叉点处的按键被按下。如果行(列)线都为高电平,说明此列(行)上没有按键按下,再把第二列(行)置低电平,其余各列(行)为高电平,读行(列)线状态;依次类推,找到当某一列(行)输出低电平时,对应的某行(列)的状态为低电平,这时就可确定按键所在的行和列。 行翻转法:列线输出为全低电平,则行线中电平由高变低的所在行为按键所在行;行线输出为全低电平,则列线中电平由高变低所在列为按键所在列。结合上述两步,可确定按键所在行和列。 8、计算机系统中,一般有哪三类总线?并请说出三类总线各自的特

单片机内的Flash与EEPROM作用及区别(精)

单片机内的 Flash 与 EEPROM 作用及区别 单片机运行时的数据都存在于 RAM (随机存储器中, 在掉电后 RAM 中的数据是无 法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用 EEPROM 或FLASHROM 等 存储器来实现。在传统的单片机系统中, 一般是在片外扩展存储器, 单片机与存储器之间通 过 IIC 或 SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开发上也要花 更多的心思。在 STC 单片机中内置了 EEPROM (其实是采用 IAP 技术读写内部 FLASH 来 实现 EEPROM ,这样就节省了片外资源,使用起来也更加方便。下面就详细介绍 STC 单 片机内置 EEPROM 及其使用方法。 flash 是用来放程序的,可以称之为程序存储器,可以擦出写入但是基本都是整个扇区进行的 . 一般来说单片机里的 flash 都用于存放运行代码,在运行过程中不能改; EEPROM 是用来保存用户数据,运行过程中可以改变,比如一个时钟的闹铃时 间初始化设定为 12:00,后来在运行中改为 6:00,这是保存在 EEPROM 里, 不怕掉电,就算重新上电也不需要重新调整到 6:00 下面是网上详细的说法,感觉不错:

FLASH 和 EEPROM 的最大区别是 FLASH 按扇区操作, EEPROM 则按字节操作, 二者寻址方法不同,存储单元的结构也不同, FLASH 的电路结构较简单,同样容量占芯片面积较小,成本自然比 EEPROM 低,因而适合用作程序存储器, EEPROM 则更多的用作非易失的数据存储器。当然用 FLASH 做数据存储器也行, 但操作比EEPROM 麻烦的多,所以更“人性化”的 MCU 设计会集成 FLASH 和 EEPROM 两种非易失性存储器,而廉价型设计往往只有 FLASH ,早期可电擦写型 MCU 则都是EEPRM 结构,现在已基本上停产了。 在芯片的内电路中, FLASH 和 EEPROM 不仅电路不同,地址空间也不同,操作方法和指令自然也不同, 不论冯诺伊曼结构还是哈佛结构都是这样。技术上, 程序存储器和非易失数据存储器都可以只用 FALSH 结构或 EEPROM 结构, 甚至可以用“变通”的技术手段在程序存储区模拟“数据存储区” ,但就算如此,概念上二者依然不同,这是基本常识问题。 EEPROM :电可擦除可编程只读存储器, Flash 的操作特性完全符合 EEPROM 的定义,属 EEPROM 无疑,首款 Flash 推出时其数据手册上也清楚的标明是EEPROM ,现在的多数 Flash 手册上也是这么标明的,二者的关系是“白马”和 “马” 。至于为什么业界要区分二者, 主要的原因是 Flash EEPROM 的操作方法和传统 EEPROM 截然不同,次要的原因是为了语言的简练,非正式文件和口语中Flash EEPROM 就简称为 Flash , 这里要强调的是白马的“白” 属性而非其“马” 属性以区别 Flash 和传统 EEPROM 。 Flash 的特点是结构简单, 同样工艺和同样晶元面积下可以得到更高容量且大数据量 下的操作速度更快,但缺点是操作过程麻烦,特别是在小数据量反复重写时, 所以在 MCU 中 Flash 结构适于不需频繁改写的程序存储器。 很多应用中,需要频繁的改写某些小量数据且需掉电非易失,传统结构的EEPROM 在此非常适合, 所以很多 MCU 内部设计了两种 EEPROM 结构, FLASH

Eeprom的读写

所看过的对24系列I2C读写时序描述最准确最容易理解的资料,尤其是关于主从器件的应答描述和页写描述,看完后明白了很多。关于页写的描述,网络上绝大部分范程都没提到页写时的数据地址必须是每页的首地址才能准确写入,而且如果写入超过一页的数据会循环覆盖当前页的数据。 关于IIC总线 I2C总线:i2c总线是Philips 公司首先推出的一种两线制串行传输总线。它由一根数据线(SDA)和一根时钟线(SDL)组成。i2c总线的数据传输过程如图3所示,基本过程为: 1、主机发出开始信号。 2、主机接着送出1字节的从机地址信息,其中最低位为读写控制码(1为读、0为写),高7位为从机器件地址代码。 3、从机发出认可信号。 4、主机开始发送信息,每发完一字节后,从机发出认可信号给主机。 5、主机发出停止信号。 I2C总线上各信号的具体说明: 开始信号:在时钟线(SCL)为高电平其间,数据线(SDA)由高变低,将产生一个开始信号。 停止信号:在时钟线(SCL)为高电平其间,数据线(SDA)由低变高,将产生一个停止信号。 应答信号:既认可信号,主机写从机时每写完一字节,如果正确从机将在下一个时钟周期将数据线(SDA)拉低,以告诉主机操作有效。在主机读从机时正确读完一字节后,主机在下一个时钟周期同样也要将数据线(SDA)拉低,发出认可信号,告诉从机所发数据已经收妥。(注:读从机时主机在最后1字节数据接收完以后不发应答,直接发停止信号)。 注意:在I2C通信过程中,所有的数据改变都必须在时钟线SCL为低电平时改变,在时钟线SCL为高电平时必须保持数据SDA信号的稳定,任何在时钟线为高电平时数据线上的电平改变都被认为是起始或停止信号。 作为一种非易失性存储器(NVM),24系列EEPROM使用的很普遍,一般作为数据量不太大的数据存储器。下面总结一下其应用的一些要点。从命名上看,24CXX中XX的单位是kbit,如24C08,其存储容量为8k bit,即1k Byte=1024 Byte。 一、工作条件 1.工作电压(VCC) 24CXX:4.5V-5.5V 24CXX-W:2.5V-5.5V 24CXX-R:1.8V-5.5V 2.输入电平定义(VIH,VIL) VIH:0.7VCC-VCC+1 VIL:-0.45V-0.3VCC 二、硬件连接 1.上拉电阻RP的取值 由于I2C总线电容要满足小于400pf的条件。从以下波形可以看出,上拉电阻越大,总线的电容越小,可以实现的数据传输率就越大,可达400khz。 [点击图片可在新窗口打开] 2.写保护脚 芯片写保护脚是高电平有效,即WP接高电平时禁止写入

单片机的各种程序

单片机的各种程序 1. 八个灯循环点亮 ORG 0030H START:MOV SP,#5FH MOV R2,#08H MOV A,#0FEH NEXT:MOV P1,A ACALL DELAY RL A DJNZ R2,NEXT MOV R2,#08H MOV A,#7FH NEXT1:MOV P1,A ACALL DELAY RR A DJNZ R2,NEXT1 SJMP START DELAY:MOV R3,#0FFH DEL1:MOV R4,#0FFH DJNZ R4,$ DJNZ R3,DEL1 RET END 2. 查表的例子 org 0000h start: mov dptr,#ledtab movc a,@a+dptr mov p0,a sjmp start ledtab: db:0c0h,0f9h,04h,0b0h,99h,92h,82h,0f8h,80h end https://www.sodocs.net/doc/0115841180.html, 0000H MOV A,#0FEH SHIFT: LCALL FLASH

RL A SJMP SHIFT FLASH: MOV R2,0AH FLASH1:MOV P1,A LCALL DELAY MOV P1,#0FFH LCALL DELAY DJNZ R2,FLASH1 RET DELAY:MOV R5,#200 D1:MOV R6,#123 NOP DJNZ R6,$ DJNZ R5,D1 RET 4.数码显示管显示2015循环 org 0000h start: loop: mov p1,#0c0h lcall DELAY mov p1,#0f9h lcall DELAY mov p1,#0a4h lcall DELAY mov p1,#0b0h lcall DELAY mov p1,#99h lcall DELAY mov p1,#92h lcall DELAY mov p1,#82h lcall DELAY mov p1,#0f8h lcall DELAY mov p1,#80h lcall DELAY

51单片机按键控制数码管程序

#define uint unsigned int #define uchar unsigned char uchar c; sbit p10=P1^0; sbit p11=P1^1; sbit p12=P1^2; sbit p13=P1^3; sbit p14=P1^4; sbit p15=P1^5; sbit p16=P1^6; sbit p17=P1^7; void delay(uint z); int b[]={0,1,2,3,4,5,6,7};//设置每一位显示的数字 unsigned char code Tab[]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};//共阳极数码管 int a[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; void main() { EA=1; EX0=1; IT0=1; P1=0xff; while(1) { for(c=0;c<8;c++)//数码管扫描显示

P2=a[c]; P0=Tab[b[c]]; delay (1); } } } void delay(uint z) { uint a,b; for(a=z;a>0;a--) for(b=110;b>0;b--); } int_0()interrupt 0 { EA=0; if(p10==0) b[0]=(b[0]+1)%10; if(p11==0) b[1]=(b[1]+1)%10; if(p12==0) b[2]=(b[2]+1)%10; if(p13==0) b[3]=(b[3]+1)%10; if(p14==0) b[4]=(b[4]+1)%10; if(p15==0) b[5]=(b[5]+1)%10; if(p16==0) b[6]=(b[6]+1)%10; if(p17==0) b[7]=(b[7]+1)%10;

STC单片机EEPROM读写程序

/* STC89C54RD+的flash空间从0x4000~0xf3ff 共90个扇区,每扇区512字节*/ // #define BaseAddr 0x1000 /* 51rc */ // #define EndSectoraddr 0x3d00 /* 51rc */ // #define EndAddr 0x3fff /* 51rc 12K eeprom */ #define BaseAddr 0x4000 #define EndSectoraddr 0xf200 #define EndAddr 0xf3ff #define UseAddr 0x1000 /* ------------- 定义扇区大小------------- */ #define PerSector 512 /* 用户程序需要记忆的数组, 用户实际使用了n-1个数据,数组长度规整到 2 4 8 16 32 64 上*/ uchar Ttotal[16] = { 0x55, /* 作为判别引导头使用,用户程序请不要修改它*/ /* 用户保存记忆的数据*/ 0x01, /* 用途说明....*/ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; uint timerForDelay, /* 专供延时用的变量*/ i, /* 循环变量*/ EepromPtr; /* eeprom读写指针*/ /* --------------- 命令定义--------------- */ #define RdCommand 0x01 /* 字节读*/ #define PrgCommand 0x02 /* 字节写*/

51单片机按键控制花样灯

51单片机按键控制花样灯 时间:2018-09-10 13:50:11 来源:51hei 作者: /**************************************************** * 本程序实现用按键控制花样灯。 * * 当K1按下时,灯从0xfe向左跑一遍; * * 当K2按下时,LED灯从0x7f向右跑一遍到了0xfe右跑回到起始位置; * * 当K3键按下时,LED灯从0xfe开始作流水灯形式运行一次,然后再流回来。 * * 当K4键按下时,LED灯先亮前四个,接着再转向亮后四个。 * * 当K5键按下时,结束任意正在进行的程序,使LED灯全部熄灭。 * ******************************************************/ ************************************************* 连接方法:P0接独立按键JP5。P2接LED灯接口JP1 * ***********************************************************/ #include //头文件,函数声明 #include //定义按键所在位 sbit K1=P0^0。 sbit K2=P0^1。 sbit K3=P0^2。 sbit K4=P0^3。 sbit K5=P0^4。 unsigned char led。 unsigned char j。 void delayms(unsigned char ms> // 1ms标准延时 { while(ms--> { for(j=0。j<110。j++>。 //还是无法设置比较标准的延时,如1S等;所以应该用定时器延时才最准确 } } void main(> { //P2=led。 unsigned int i。

51单片机内部EEPROM的应用

用51hei-5板子学习单片机内部EEPROM的应用 STC89C51、52内部都自带有2K字节的EEPROM,54、55和58都自带有16K字节的EEPRO M,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次以上,先来介绍下ISP与IAP的区别和特点。 ISP:In System Programable 是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。比如我们通过电脑给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。 IAP:In Application Programable 是指在应用编程,就是片子提供一系列的机制(硬件/软件上的)当片子在运行程序的时候可以提供一种改变flash数据的方法。通俗点讲,也就是说程序自己可以往程序存储器里写数据或修改程序。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到存储区。大家要注意千万不要尝试去擦除这段ISP引导程序,否则恐怕以后再也下载不了程序了。STC单片机内部有几个专门的特殊功能寄存器负责管理ISP/IAP 功能的,见表1。 表1 ISP/IAP相关寄存器列表 名称地址功能描述D7D6D5D4D3D2D1D0复位值ISP_DATA E2h Flash数据寄存器1111 1111 ISP_ADDRH E3h Flash高字节地址寄 存器0000 0000 ISP_ADDRL E4h Flash低字节地址寄 存器0000 0000 ISP_CMD E5h Flash命令模式寄存 器 ----------MS2MS1MS0xxxx x000 ISP_TRIG E6h Flash命令触发寄存 器 xxxx xxxx ISP_CONTR E7h ISP/IAP 控制寄存器ISPEN SWBS SWRST----WT2WT1WT0000x x000 ISP_DATA:ISP/IAP操作时的数据寄存器。

第13讲51单片机按键电路

标题:键盘接口电路 教学目标与要求: 1.键盘去抖动和连接、控制方式 2.独立式按键及其接口电路 3.矩阵式键盘及其接口电路 授课时数:2 教学重点:.矩阵式键盘及其接口电路 教学内容及过程: 一、键盘接口概述 1、按键开关去抖动问题 机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动,然后其触点才稳定下来。其抖动过程如图9-11所示,抖动时间的长短与开关的机械特性有关,一般为5 10 ms 在触点抖动期间检测按键的通与断状态,可能导致判断出错,即按键一次按下或释放被错误地认为是多次操作,这种情况是不允许出现的。为了克服按键触点机械抖动所致的检测误判,必须采取去抖动措施。这一点可从硬件、软件两方面予以考虑。在键数较少时,可采用硬件去抖,而当键数较多时,采用软件去抖。在硬件上可采用在键输出端加R-S触发器(双稳态触发器)或单稳态触发器构成去抖动电路。图9-12是一种由R-S触发器构成的去抖动电路,当触发器一旦翻转,触点抖动不会对其产生任何影响。 软件上采取的措施是:在检测到有按键按下时,执行一个10 ms左右(具体时间应视所使用的按键进行调整)的延时程序后,再确认该键电平是否仍保持闭合状态电平,若仍保持闭合状态电平,则确认该键处于闭合状态。同理,在检测到该键释放后,也应采用相同的步 骤进行确认,从而可消除抖动的影响。

2.编制键盘程序 一个完善的键盘控制程序应具备以下功能: (1) 检测有无按键按下,并采取硬件或软件措施,消除键盘按键机械触点抖动的影响。 (2) 有可靠的逻辑处理办法。每次只处理一个按键,其间对任何按键的操作对系统不产生影响,且无论一次按键时间有多长,系统仅执行一次按键功能程序。 (3) 准确输出按键值(或键号),以满足跳转指令要求。 二、独立式按键 单片机控制系统中,往往只需要几个功能键,此时,可采用独立式按键结构。 1. 独立式按键结构 独立式按键是直接用I/O口线构成的单个按键电路,其特点是每个按键单独占用一根I/O口线,每个按键的工作不会影响其它I/O口线的状态。独立式按键的典型应用如图7.4所示。 独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一根I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。 2.矩阵式键盘 I/O端线分为行线和列线,按键跨接在行线和列线上,按键按下时,行线与列线发生短路。特点: ①占用I/O端线较少; ②软件结构教复杂。 适用于按键较多的场合。 3.键盘扫描控制方式 ⑴程序控制扫描方式 键处理程序固定在主程序的某个程序段。 特点:对CPU工作影响小,但应考虑键盘处理程序的运行间隔周期不能太长,否则会影响对键输入响应的及时性。 ⑵定时控制扫描方式 利用定时/计数器每隔一段时间产生定时中断,CPU响应中断后对键盘进行扫描。 特点:与程序控制扫描方式的区别是,在扫描间隔时间内,前者用CPU工作程序填充,后者用定时/计数器定时控制。定时控制扫描方式也应考虑定时时间不能太长,否则会影响对键输入响应的及时性。 ⑶中断控制方式 中断控制方式是利用外部中断源,响应键输入信号。 特点:克服了前两种控制方式可能产生的空扫描和不能及时响应键输入的缺点,既能及时处理键输入,又能提高CPU运行效率,但要占用一个宝贵的中断资源。 三、独立式按键及其接口电路 1、按键直接与I/O口连接

STC单片机EEPROM的应用和程序

STC单片机EEPROM的应用和程序 (2009-04-22 21:58:34) 转载▼ 标签: 杂谈 分类:Program 最近,由于工作的需要,用STC89C52来开发新产品,要用天STC的Eeprom的功能,上网也找了一点资料,得到很大帮助,真的非常感谢。程序是我在网上摘录的,调试通过了,不过我产品在用动态扫描显示的,由于在Eeprom擦除时要用几十毫秒,会有一闪烁的。不过这是正常的。 单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无 法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现。在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开发上也要花更多的心思。在STC 单片机中内置了EEPROM(其实是采用IAP 技术读写内部FLASH 来 实现EEPROM),这样就节省了片外资源,使用起来也更加方便。下面就详细介绍STC 单片机内置EEPROM 及其使用方法。 STC 各型号单片机内置的EEPROM 的容量各有不同,见下表: (内部EEPROM 可以擦写100000 次以上) 上面提到了IAP,它的意思是"在应用编程",即在程序运行时程序存储器可由程序自 身进行擦写。正是是因为有了IAP,从而可以使单片机可以将数据写入到程序存储器中,使得数据如同烧入的程序一样,掉电不丢失。当然写入数据的区域与程序存储区要分开来,以使程序不会遭到破坏。 要使用IAP 功能,与以下几个特殊功能寄存器相关: ISP_DATA:ISP/IAP 操作时的数据寄存器。 ISP/IAP 从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处 ISP_ADDRH:ISP/IAP 操作时的地址寄存器高八位。 ISP_ADDRL:ISP/IAP 操作时的地址寄存器低八位。 ISP_CMD:ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效。 ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。 当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG 先写入0x46,再写入0xb9,ISP/IAP 命令才会生效。 单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节) STC89C51RC,STC89LE51RC 0x2000 共八个扇区 STC89C52RC,STC89LE52RC 0x2000 共八个扇区 STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区 STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区 STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区 寄存器标识地址名称7 6 5 4 3 2 1 0 初始值 ISP_DATA 0xE2 ISP/IAP闪存数据寄存器11111111 ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000

单片机程序汇总,大家参考一下剖析

第八章4节支持手打!! #include #include #define PI 3.1415 unsigned int num; void main() { while (1) { for (num = 0 ; num < 360 ; num++) P2= 127 +127 * sin((float)num / 180 * PI); } } #include #define DAC0832 XBYTE[0xfeff] //设置DAC0832的访问地址unsigned char num; void main() { while (1) { for (num = 0 ; num < 255 ; num++) //上升段波形 DAC0832=num; for (num = 255 ; num > 0 ; num--) //下降段波形

DAC0832=num; //DAC0832转换输出 } } #include #include #define DAC1 XBYTE[0xfeff] //设置1#DAC0832输入锁存器的访问地址#define DAC2 XBYTE[0xfdff] //设置2#DAC0832输入锁存器的访问地址#define DAOUT XBYTE[0xefff] //两个DAC0832的DAC寄存器访问地址void main (void){ unsigned char num; //需要转换的数据 while(1){ for(num =0; num <=255; num++){ DAC1 = num; //上锯齿送入1#DAC DAC2 = 255-num; //下锯齿送入2#DAC DAOUT = num; //两路同时进行D/A转换输出 } } } /*发送程序*/ #include #define uchar unsigned char

相关主题