第八届客观题(部分):
8051单片机堆栈指针的作用是:指明栈顶的位置
单片机和PC通讯使用MAX232芯片为了电平转换
空闲状态下,Tx引脚上电平为高
使用非整数的晶振是为了获得精准的波特率
通讯距离为800M时候使用RS485
串口TTL 几M RS-232 30M CAN BUS 10KM
I2C在读写操作时开始信号为SCL为高电平期间,SDA由高变为低
当电路有用信号为某一固定频率时候,选用带通滤波器
直流电源的滤波电路宜选用低通滤波器
pdata unsigned char 和 xdata unsigned char 分配在外部的RAM中
PWM功能的单片机可以通过滤波器实现DAC功能
15F61S2可以使用内部RC振荡器,也可以使用外部晶振工作
IO:对IO口直接赋值操作
MM的代码量比较小:存储器映射
温度芯片:具体功能我也不用过多解释了,芯片手册都有简单贴一下指令集:
代码可以实现每隔一秒刷新实时温度
因为在比赛的时候部分驱动代码是给出的所以我们在操作的时候只需要编写温度转换函数:
ds18b20.v:
#ifndef __DS18B20_H#define __DS18B20_H#include <intrins.h>//单总线延时函数voidDelay_OneWire(unsignedintt); voidWrite_DS18B20(unsignedchardat); unsignedcharRead_DS18B20(void); bitinit_ds18b20(void); unsignedchartemget(); voidDelay500us(); #endif
ds18b20.c:
#include "stc15f2k60s2.h"#include <ds18b20.h>sbitDQ=P1^4; //单总线接口//单总线延时函数voidDelay_OneWire(unsignedintt) { unsignedchari; while(t--){ for(i=0; i<8; i++); } } //通过单总线向DS18B20写一个字节voidWrite_DS18B20(unsignedchardat) { unsignedchari; for(i=0;i<8;i++) { DQ=0; DQ=dat&0x01; Delay_OneWire(5); DQ=1; dat>>=1; } Delay_OneWire(5); } //从DS18B20读取一个字节unsignedcharRead_DS18B20(void) { unsignedchari; unsignedchardat; for(i=0;i<8;i++) { DQ=0; dat>>=1; DQ=1; if(DQ) { dat|=0x80; } Delay_OneWire(5); } returndat; } //DS18B20设备初始化bitinit_ds18b20(void) { bitinitflag=0; DQ=1; Delay_OneWire(12); DQ=0; Delay_OneWire(80); DQ=1; Delay_OneWire(10); initflag=DQ; Delay_OneWire(5); returninitflag; } //--------------------------------------------------//------------这部分代码自己编写----------------------unsignedchartemget() { unsignedchartemp; unsignedcharlow,high; init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0x44); Delay500us(); Delay500us(); init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0xbe); low=Read_DS18B20(); high=Read_DS18B20(); temp=high<<4; temp|= (low>>4); returntemp; } voidDelay500us() //@11.0592MHz{ unsignedchari, j; _nop_(); _nop_(); i=6; j=93; do { while (--j); } while (--i); }
在main.c中:
#include <stc15f2k60s2.h>#include <intrins.h>#include <ds18b20.h>#define uchar unsigned char #define uint unsigned int ucharseg[]={ 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e, 0xff}; uchartemp=0; uinttim; ucharyi=16, er=16,san=12; ucharguan=16; ucharflag=0; voidallinit(); voiddisplay(ucharyi,er,san,si,wu,liu,qi,ba); voidDelay1ms(); voidDelayms(uintms); voidTimer0Init(); voidmain() { allinit(); Timer0Init(); while(1) { display(yi,er,san,guan,guan,guan,guan,guan); } } voidallinit() { P2=0xa0;P0=0x00; P2=0x80;P0=0xff; P2=0xe0;P0=0xff; P2=0xc0;P0=0xff; } voiddisplay(ucharyi,er,san,si,wu,liu,qi,ba) { P2=0xe0;//段选P0=seg[yi]; P2=0xc0;//位选P0=0x01; Delay1ms(); Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[er]; P2=0xc0;//位选P0=0x02; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[san]; P2=0xc0;//位选P0=0x04; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[si]; P2=0xc0;//位选P0=0x08; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[wu]; P2=0xc0;//位选P0=0x10; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[liu]; P2=0xc0;//位选P0=0x20; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[qi]; P2=0xc0;//位选P0=0x40; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[ba]; P2=0xc0;//位选P0=0x80; Delay1ms();Delay1ms();Delay1ms(); } voidDelay1ms() //@11.0592MHz{ unsignedchari, j; _nop_(); _nop_(); _nop_(); i=11; j=190; do { while (--j); } while (--i); } voidDelayms(uintms) //@11.0592MHz{ unsignedchari, j,k; for(k=ms;k>0;k--) { _nop_(); _nop_(); _nop_(); i=11; j=190; do { while (--j); } while (--i); } } voidTimer0Init(void) //1毫秒@11.0592MHz{ AUXR|=0x80; //定时器时钟1T模式TMOD&=0xF0; //设置定时器模式TL0=0xCD; //设置定时初值TH0=0xD4; //设置定时初值TF0=0; //清除TF0标志TR0=1; //定时器0开始计时EA=1;//总中断开关ET0=1;//定时器0中断开始} voidtimer0() interrupt1{ tim++; if(tim==1000) { tim=0; temp=temget(); yi=temp%100/10; er=temp%10; } }
中断的优先级问题:
interrupt1是中断序号 这是定时器0中断的意思 只要用定时器0中断 必须用此句。
interrupt 1是定时器0
interrupt 0 外中断0 interrupt2 外中断1
interrupt 3 定时器1
interrupt 4 串行口中断