proteus小笔记2.docx
《proteus小笔记2.docx》由会员分享,可在线阅读,更多相关《proteus小笔记2.docx(16页珍藏版)》请在冰点文库上搜索。
proteus小笔记2
ADC模数转换:
给PA7口一个0---5V连续可调的电压值,AVCC提供5V的参考电压,通过数码管加于显示!
代码:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#pragmainterrupt_handlertime0_comp_isr:
20
#pragmainterrupt_handleradc_isr:
15
flashucharled_7[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
flashucharposition[4]={0xfe,0xfd,0xfb,0xf7};
uchardis_buff[4]={0,0,0,0},posit;
chartime_2ms_ok;
voiddelay_ms(uintms)
{
uinti,j;
for(i=0;ifor(j=0;j<1141;j++);
}
voidadc_to_disbuffer(uintadc)//////////////////////把数据植入显示缓冲区
{
uchari;
for(i=0;i<=3;i++)
{
dis_buff[i]=adc%10;
adc/=10;
}
}
voidtime0_comp_isr(void)///////timer0比较匹配中断(2ms)
{
time_2ms_ok=1;
}
voidadc_isr(void)/////////////ADC转换完成中断
{
uintadc_date_1,adc_date_2,adc_date,adc_v;
adc_date_1=ADCL;////////////读取数据寄存器的值(先读低位在读高位)
adc_date_2=ADCH;
adc_date=adc_date_2*256+adc_date_1;
adc_v=(unsignedlong)adc_date*5000/1024;
adc_to_disbuffer(adc_v);
}
voiddisplay(void)/////////////////显示数据
{
PORTA|=0x0f;
PORTC=led_7[dis_buff[posit]];
if(posit==3)
PORTC|=0x80;
PORTA&=position[posit];
if(++posit>=4)
posit=0;
}
voidmain(void)
{
DDRA=0x0f;
PORTA=0x0f;
DDRC=0xff;
PORTC=0;
CLI();
TCCR0=0x0b;///////////定时器设置,64分频(4MHZ/64=62.5KHZ),CTC模式
TCNT0=0;
OCR0=0x7c;////OCR0=0x7c(124),(124+1)/62.5KHZ=2ms
TIMSK=0x02;
///ADC设置
ADMUX=0x47;//参考电压AVCC,ADC7单端输入
SFIOR&=0x1f;
SFIOR|=0x60;//选择T/C0比较匹配中断为ADC触发源
ADCSRA=0xad;//ADC允许,自动触发转化,ADC转换中断允许,ADCclk=125KHZ
SEI();
while
(1)
{
if(time_2ms_ok)//每两秒进行一次扫描
{
display();
time_2ms_ok=0;
}
}
}
AD转换:
给PA0输入0—5V的模拟电压,给AREF一5V电压,用数码管显示数字量(0—1023)。
代码:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
flashucharled_7[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
butter[4]={0};
uintdate;
voiddelay_ms(uintms)
{
uinti,j;
for(i=0;ifor(j=0;j<1141;j++);
}
voiddisplay(charshu,charwei)
{
DDRB=0xff;
DDRC=0xff;
PORTB=led_7[shu];
PORTC=~BIT(wei);
delay_ms
(2);
PORTC=0xff;//注意此处,每显示以为都要把其
}//关闭,否则会影响下一位的显示
voidchaishu(void)
{
inti;
for(i=0;i<4;i++)
{
butter[3-i]=date%10;
date=date/10;
}
}
voidad(void)
{
DDRA&=~BIT(0);
PORTA&=~BIT(0);
ADMUX=0;//AREF参考电压,左对齐,PA0单端输入
ADCSRA=0xC0;//使能ADC,开始转换(一次)
while(!
(ADCSRA&BIT(ADIF)));//查询是否转换完毕
date=ADCL;//读取数据,先读低位
date=ADCH*256+date;
ADCSRA|=BIT(ADIF);//清零标志位
}
voidmain(void)
{
chari;
while
(1)
{
ad();
chaishu();
for(i=0;i<4;i++)
{
display(butter[i],i);
}
}
}
USART通信:
两片单片机间的的usart通信,主机传送数据给从机,从机接受数据并用LED加于显示。
。
。
主机:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definefosc8000000
voiddelay_ms(uintms)
{
uinti,j;
for(i=0;ifor(j=0;j<1141;j++);
}
voidusart_init(uintbuad)//buad为波特率
{
uintUBRR_1;
CLI();
UCSRB=0;
UCSRA=0;
UCSRC=0b10100110;//在写UCSRC时候第一位必须为1;异步;
//偶校验;一位停止位;
UBRR_1=fosc/16/buad-1;//波特率的计算
UBRRL=UBRR_1&0xff;//设置波特率
UBRRH=(UBRR_1>>8);
UCSRB=0b10011000;//RX中断允许;允许接受;允许发送;
SEI();
//DDRD|=BIT
(1);//接受发送管脚设置,但最好还是设置一下
//PORTD|=BIT(0);
}
voidsend(ucharx)
{
CLI();
while(!
UCSRA&BIT(5));//如果数据寄存器为空
UDR=x;
while(!
UCSRA&BIT(6));//发送完成
UCSRA|=BIT(6);//清零发送完成标志位
SEI();
}
voidmain()
{
chari=10;
usart_init(9600);
while
(1)
{
send(i++);
delay_ms(1000);
}
}
从机:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definefosc8000000
#pragmainterrupt_handlerrx:
12//接受中断
charflag=0,date;
voiddelay_ms(uintms)
{
uinti,j;
for(i=0;ifor(j=0;j<1141;j++);
}
voidrx(void)
{
UCSRB&=~BIT(RXCIE);//关闭中断读取数据
date=UDR;
//flag=1;
PORTB=date;
UCSRB|=BIT(RXCIE);//打开中断
}
voidusart_init(uintbuad)//和主机的设置全部一样
{
uintUBRR_1;
CLI();
UCSRB=0;
UCSRA=0;
UCSRC=0b10100110;
UBRR_1=fosc/16/buad-1;
UBRRL=UBRR_1&0xff;
UBRRH=(UBRR_1>>8);
UCSRB=0b10011000;
SEI();
//DDRD|=BIT
(1);
//PORTD|=BIT(0);
}
voidsend(ucharx)
{
CLI();
while(!
UCSRA&BIT(5));
UDR=x;
while(!
UCSRA&BIT(6));
UCSRA|=BIT(6);
SEI();
}
voidmain()
{
DDRB=0xff;
usart_init(9600);
while
(1)
{
}
}
总结:
usart为全双工通信,发送和接受被同时允许时,当URD为空时,直接写入数据就为发送,数据移出后发送完成标志位置位;当外部数据写入URD时,接收完成标志位置位,表示接受完成!
USART实行自发自收:
在一个单片机中实行自发自收,并在接受中断中用LED加于显示!
代码:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definefosc8000000
#pragmainterrupt_handlerrx:
12
charflag=0,date;
voiddelay_ms(uintms)
{
uinti,j;
for(i=0;ifor(j=0;j<1141;j++);
}
voidrx(void)
{
UCSRB&=~BIT(RXCIE);
date=UDR;
PORTC=date;
UCSRB|=BIT(RXCIE);
}
voidusart_init(uintbuad)
{
uintUBRR_1;
CLI();
UCSRB=0;
UCSRA=0;
UCSRC=0b10100110;//在写UCSRC时候第一位必须为1;异步;
//偶校验;一位停止位;
UBRR_1=fosc/16/buad-1;//波特率的计算
UBRRL=UBRR_1&0xff;//设置波特率
UBRRH=(UBRR_1>>8);
UCSRB=0b10011000;//RX中断允许;允许接受;允许发送;
SEI();
DDRD|=BIT
(1);//接受发送管脚设置,但最好还是设置一下
PORTD|=BIT(0);
}
voidsend(ucharx)
{
CLI();
while(!
UCSRA&BIT(5));
UDR=x;
while(!
UCSRA&BIT(6));
UCSRA|=BIT(6);
SEI();
}
voidmain()
{
chari;
delay_ms
(1);
DDRC=0xff;
usart_init(9600);
while
(1)
{
send(i++);
delay_ms(1000);
}
}
单片机与PC的串口通信:
用PC给单片机发送信号并用LCD显示,单片机每隔一秒给PC发送一个数据。
在虚拟终端上显示。
代码:
#include
#include
#include"1602_1.c"
#defineuintunsignedint
#defineucharunsignedchar
#definefosc8000000
#pragmainterrupt_handlerrx:
12
charflag=0,date_1,date[4]={0};
intsum;
voidrx(void)
{
UCSRB&=~BIT(RXCIE);
date_1=UDR;
lcd_da(date_1);
UCSRB|=BIT(RXCIE);
}
voidusart_init(uintbuad)
{
uintUBRR_1;
CLI();
UCSRB=0;
UCSRA=0;
UCSRC=0b10000110;//在写UCSRC时候第一位必须为1;异步;
//无校验;一位停止位;
UBRR_1=fosc/16/buad-1;//波特率的计算
UBRRL=UBRR_1&0xff;//设置波特率
UBRRH=(UBRR_1>>8);
UCSRB=0b10011000;//RX中断允许;允许接受;允许发送;
SEI();
DDRD|=BIT
(1);//接受发送管脚设置,但最好还是设置一下
PORTD|=BIT(0);
}
voidsend(ucharx)
{
CLI();
while(!
(UCSRA&BIT(5)));
UDR=x;
while(!
(UCSRA&BIT(6)));
UCSRA|=BIT(6);
SEI();
}
voidmain()
{
chari=48,j=0;
delay_ms
(1);
DDRC=0xff;
usart_init(9600);
port_init();
lcd_init();
lcd_clear();
write_da(0,0,0);
delay_ms(1000);
while
(1)
{
if((j++)==4)
{
j=0;
send(0x0a);//每四个换一行
send(0x0d);
delay_ms(100);
}
send(i++);
delay_ms(1000);
}
}
虚拟串口的使用:
使用虚拟串口和单片机进行通讯,代码同上!
(注意个参数的设置)