久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標(biāo)題:
寢室電量提示系統(tǒng)(2)—下位機(jī)的設(shè)計(jì)
[打印本頁(yè)]
作者:
huge
時(shí)間:
2015-2-19 01:18
標(biāo)題:
寢室電量提示系統(tǒng)(2)—下位機(jī)的設(shè)計(jì)
本帖最后由 huge 于 2015-2-19 01:23 編輯
本制作程序的上位機(jī)詳見(jiàn):
http://www.zg4o1577.cn/bbs/dpj-31601-1.html
耗了我1個(gè)半月的時(shí)間,終于算是結(jié)束了。廢話不說(shuō),直接步入正題。
下位機(jī)的設(shè)計(jì)是以ATmega16為核心,采用時(shí)鐘芯片DS1302,RS-232串行通信接口,MAX232電平轉(zhuǎn)換芯片(因?yàn)樵赑roteus中串行接口電平已經(jīng)轉(zhuǎn)換了,所以并沒(méi)有加入仿真中)。
/*****************************************************
【Proteus仿真效果】
http://player.youku.com/player.php/sid/XNDc5MDA0MzQ0/v.swf
/*****************************************************
【CVAVR下的源程序】
#include <mega16.h>
#asm
.equ __ds1302_port=0x15
.equ __ds1302_io=7
.equ __ds1302_sclk=6
.equ __ds1302_rst=5
#endasm
#include <ds1302.h>
#define uchar unsigned char
uchar c0;
uchar dis_buff[14],time[7];
uchar roomno[50][5];
int time100ms;
uchar time_counter100ms,time_counter1s;
uchar i,j,choice,room,roomnum,move,moveh,countnum,receivenum,sendnum;
bit time100ms_ok,time1s_ok,dot0,k,key;
//RSDA PORTC.1
//CLK PORTC.0
//RCK PORTC.2
//138使能E PORTC.4
flash uchar signature[][32]={ // "以下房間電量不足",點(diǎn)陣16x16,長(zhǎng)度32字節(jié)};
flash uchar number[][16]={ // "0 1 2 3 4 5 6 7 8 9 ",點(diǎn)陣8x16,長(zhǎng)度16字節(jié) };
flash uchar dot[][16]={ // ":"點(diǎn)陣8x16,長(zhǎng)度16字節(jié)};
flash uchar datachars[][16]={ // "今天是年月日",點(diǎn)陣8x16,長(zhǎng)度16字節(jié)};
#ifndef RXB8
#define RXB8 1
#endif
#ifndef TXB8
#define TXB8 0
#endif
#ifndef UPE
#define UPE 2
#endif
#ifndef DOR
#define DOR 3
#endif
#ifndef FE
#define FE 4
#endif
#ifndef UDRE
#define UDRE 5
#endif
#ifndef RXC
#define RXC 7
#endif
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
void sendbyteR(uchar temp) //發(fā)送數(shù)據(jù)
{
uchar c;
for(c=0;c<8;c++)
{
PORTC.1=(temp)&(0x01);
temp=temp>>1;
PORTC.0=0x01; //上升沿
PORTC.0=0;
}
}
void time_to_disbuffer() // 日期、時(shí)鐘、天數(shù)送顯示緩沖區(qū)函數(shù)
{
unsigned char i,j0=0;
for (i=0;i<=6;i++)
{
dis_buff[j0++] = time[i]%10;
dis_buff[j0++] = time[i]/10;
}
}
uchar s,chartemp[10];
flash unsigned char *disword[36];
void disdata() //字幕緩沖函數(shù)
{
uchar i;
for(i=0;i<=7;i++) disword[i]=&number[1][0];
for(i=8;i<=13;i++) disword[i]=&datachars[i-8][0];
for(i=14;i<=17;i++) disword[i]=&number[2*dis_buff[27-i]][0];
disword[18]=&datachars[6][0];
disword[19]=&datachars[7][0];
disword[20]=&number[2*dis_buff[9]][0];
disword[21]=&number[2*dis_buff[8]][0];
disword[22]=&datachars[8][0];
disword[23]=&datachars[9][0];
disword[24]=&number[2*dis_buff[7]][0];
disword[25]=&number[2*dis_buff[6]][0];
disword[26]=&datachars[10][0];
disword[27]=&datachars[11][0];
disword[28]=&number[1][0];
disword[29]=&number[2*dis_buff[5]][0];
disword[30]=&number[2*dis_buff[4]][0];
disword[31]=&dot[0][0];
disword[32]=&number[2*dis_buff[3]][0];
disword[33]=&number[2*dis_buff[2]][0];
disword[34]=&number[1][0];
disword[35]=&number[1][0];
}
void move_left() //字幕左移函數(shù)
{
uchar i;
for(i=0;i<=9;i++)
chartemp[i] = *(disword[i+s]+j);
for(i=0;i<=8;i++)
chartemp[i]=(chartemp[i]<<moveh)|(chartemp[i+1]>>(8-moveh));
}
void todispcase3()
{
choice=3;
if(time100ms_ok)
{
time100ms_ok=0;
if(++moveh>=8)
{
moveh=0;
if(++s>=27) s=0;
}
}
if(time1s_ok)
{
time1s_ok=0;
rtc_get_date(&time[3],&time[4],&time[5]);
rtc_get_time(&time[2],&time[1],&time[0]);
time_to_disbuffer();
disdata();
}
}
void display(uchar diff) //掃描顯示函數(shù)
{
PORTC.4=0;
switch(diff)
{
case 0: //顯示時(shí)間(小時(shí),分)
{
sendbyteR(number[1][j]);
sendbyteR(number[1][j]);
sendbyteR(number[dis_buff[2]*2][j]);
sendbyteR(number[dis_buff[3]*2][j]);
if(dot0) sendbyteR(dot[0][j]);
else sendbyteR(number[1][j]);
sendbyteR(number[dis_buff[4]*2][j]);
sendbyteR(number[dis_buff[5]*2][j]);
sendbyteR(number[1][j]);
break;
}
case 1: //顯示缺電提示字幕
{
sendbyteR(signature[3+4*k][j*2+1]);
sendbyteR(signature[3+4*k][j*2]);
sendbyteR(signature[2+4*k][j*2+1]);
sendbyteR(signature[2+4*k][j*2]);
sendbyteR(signature[1+4*k][j*2+1]);
sendbyteR(signature[1+4*k][j*2]);
sendbyteR(signature[0+4*k][j*2+1]);
sendbyteR(signature[0+4*k][j*2]);
break;
}
case 2: //顯示缺電寢室號(hào)
{
sendbyteR(number[1][j]);
sendbyteR(number[(roomno[room][4])*2][j+move]);
sendbyteR(number[(roomno[room][3])*2][j+move]);
sendbyteR(number[(roomno[room][2])*2][j+move]);
sendbyteR(number[(roomno[room][1])*2][j+move]);
sendbyteR(number[(roomno[room][0])*2][j+move]);
sendbyteR(number[1][j]);
sendbyteR(number[1][j]);
break;
}
case 3: //左移顯示時(shí)間(年,月,日,小時(shí),分)
{
move_left();
sendbyteR(chartemp[7]);
sendbyteR(chartemp[6]);
sendbyteR(chartemp[5]);
sendbyteR(chartemp[4]);
sendbyteR(chartemp[3]);
sendbyteR(chartemp[2]);
sendbyteR(chartemp[1]);
sendbyteR(chartemp[0]);
break;
}
}
PORTA=j;
PORTC.2=1;
PORTC.2=0;
PORTC.4=1;
if(++j>=16) j=0;
}
// USART Receiver buffer
#define RX_BUFFER_SIZE 11
#define UART_BEGIN_STX 0xBB
#define UART_END_STX 0xEE
char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE <= 256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif
// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if(!rx_buffer_overflow)
{
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
rx_wr_index++;
switch(rx_wr_index)
{
case 1: // 檢驗(yàn)起始字符
if (data != UART_BEGIN_STX)
rx_wr_index = 0;
break;
case 10:
if (data !=(rx_buffer[1]^rx_buffer[4]))
rx_wr_index = 0;
break;
case 11:
rx_wr_index=0;
if (data == UART_END_STX) rx_buffer_overflow=1;
break;
}
}
}
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index++];
#if RX_BUFFER_SIZE != 256
if (rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#endif
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
// USART Transmitter buffer
#define TX_BUFFER_SIZE 11
char tx_buffer[TX_BUFFER_SIZE];
#if TX_BUFFER_SIZE <= 256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
{
--tx_counter;
UDR=tx_buffer[tx_rd_index++];
#if TX_BUFFER_SIZE != 256
if (tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
#endif
}
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer[tx_wr_index++]=c;
#if TX_BUFFER_SIZE != 256
if (tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
#endif
++tx_counter;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif
// Standard Input/Output functions
#include <stdio.h>
// Timer 0 output compare interrupt service routine
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
// Place your code here
display(choice); //定時(shí)2ms,2ms顯示掃描一次
if(++time_counter100ms>=50)
{
time_counter100ms=0; //定時(shí)100ms
time100ms_ok=1;
time100ms++;
if(++time_counter1s>=10)
{
time_counter1s=0;
time1s_ok=1; //定時(shí)1s
dot0=~dot0; //秒閃爍
}
}
}
void main(void) //主函數(shù)
{
PORTA=0x00;
DDRA=0x0F;
PORTC=0x00;
DDRC=0xF7;
PORTD=0x00;
DDRD=0x02;
// Mode: CTC top=OCR0
TCCR0=0x0B; // Timer/Counter 0 initialization
TCNT0=0x00; // Clock source: System Clock
OCR0=0x7C; // Clock value: 62.500 kHz
// USART initialization
UCSRA=0x00;
UCSRB=0xD8; // Communication Parameters: 8 Data, 1 Stop, No Parity
UCSRC=0x86; // USART Receiver: On,USART Transmitter: On
UBRRH=0x00; // USART Mode: Asynchronous
UBRRL=0x19; // USART Baud Rate: 9600
countnum=0;
roomnum=0; //roomnum為要顯示寢室的個(gè)數(shù)
room=0;
move=0;
rtc_init(1,2,3); // 初始化DS1302
//rtc_get_time(&time[2],&time[1],&time[0]);
time[6]=20;time[5]=12;time[4]=11;time[3]=12;
time[2]=0;time[1]=0;time[0]=0;
time_to_disbuffer();
disdata();
choice=0;
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
if (rx_buffer_overflow)
{ // 有剛接收到數(shù)據(jù)包需要處理
receive:
PORTC.4=0;
switch(rx_buffer[1])
{
case 0xA2:
for(i=2;i<=8;i++)
time[8-i]=rx_buffer[i];
countnum=1;
break;
case 0xA8:
for(i=2;i<=6;i++)
roomno[roomnum][i-2]=rx_buffer[i];
roomnum++;
break;
case 0xAF:
receivenum=rx_buffer[2];
TIMSK=0x00;
time100ms=0;
choice=0;
room=0;
move=0;
countnum=0;
roomnum=0;
s=0;
moveh=0;
time100ms=0;
break;
default:
sendnum=0x01;
break;
}
rx_buffer_overflow = 0; // 允許接收下一個(gè)數(shù)據(jù)包
}
if(((countnum+roomnum)==receivenum)&(receivenum>0))
{
sendnum=0x00;
putchar(UART_BEGIN_STX);
putchar('AA');
putchar(sendnum);
for(c0=0;c0<=5;c0++) putchar('00');
putchar('AA');
putchar(UART_END_STX);
TIMSK=0x02;
}
if(roomnum>0) key=1;
else key=0;
rtc_set_date(time[3],time[4],time[5]);
rtc_set_time(time[2],time[1],time[0]);
time_to_disbuffer();
//顯示模塊處理
//while((countnum+roomnum)==receivenum)
while(((countnum+roomnum)==receivenum)&(receivenum>0))
{
if(rx_buffer_overflow) goto receive; //判斷是否更新顯示信息
if(key) //顯示缺電提示判斷
{
if(time100ms<=210)
{
todispcase3();
}
else if(time100ms<=280)
{
choice=0;
if(time1s_ok)
{
time1s_ok=0;
rtc_get_time(&time[2],&time[1],&time[0]);
time_to_disbuffer();
}
} //顯示現(xiàn)在時(shí)間
else if(time100ms<=290)
{
k=0;
choice=1;
} //顯示“以下房間”
else if(time100ms<=300)
{
k=1;
choice=1;
} //顯示“電量不足”
else
{
choice=2;
if(time100ms_ok)
{
time100ms_ok=0;
if(++move>=16)
{
move=0;
if(++room>=roomnum)
{
room=0;
s=0;
moveh=0;
time100ms=0;
time100ms_ok=0;
}
}
} //顯示“缺電寢室”,1.6s換一個(gè)寢室號(hào)
}
}
else
{
if(time100ms<=210) //只顯示現(xiàn)在時(shí)間
{
todispcase3();
}
else if(time100ms<=3810)
{
choice=0;
if(time1s_ok)
{
time1s_ok=0;
rtc_get_time(&time[2],&time[1],&time[0]);
time_to_disbuffer();
}
}
else
{
s=0;
moveh=0;
time100ms=0;
time100ms_ok=0;
}
}
}
}
}
復(fù)制代碼
/*****************************************************
最后效果怎么說(shuō)呢,感覺(jué)在Proteus仿真中的時(shí)間會(huì)慢一點(diǎn),1s并不是所謂的1s,在顯示模式的切換下也有一定的BUG。很想入手個(gè)二手的點(diǎn)陣屏,看看真實(shí)的效果怎樣,進(jìn)一步修改。呵呵。
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
欧美一级片在线观看
|
欧美一级在线视频
|
日韩中文字幕在线
|
久久高清
|
国产精品中文字幕在线
|
国产日韩一区二区三区
|
性在线
|
欧美日韩手机在线观看
|
久久国产精品视频
|
精品福利视频一区二区三区
|
一区二区三区在线免费观看
|
中文字幕一区二区三区四区不卡
|
日韩中文字幕视频在线观看
|
亚洲精品成人
|
免费观看a级毛片在线播放 黄网站免费入口
|
白浆在线
|
亚洲成av人片在线观看无码
|
中国xxxx性xxxx产国
|
国产综合区
|
欧美日韩一区二区在线播放
|
91.com视频
|
日韩在线播放网址
|
亚洲欧美日韩电影
|
欧美日韩在线播放
|
国产在线拍偷自揄拍视频
|
国产欧美日韩精品一区二区三区
|
青青草这里只有精品
|
国产高清视频在线观看
|
日本久久一区二区三区
|
日韩欧美国产一区二区
|
国产一区影院
|
欧美激情视频一区二区三区在线播放
|
一级黄色在线
|
性高朝久久久久久久3小时 av一区二区三区四区
|
婷婷色网
|
av在线免费观看网站
|
精品乱码久久久久
|
www.一区二区三区
|
中文字幕在线第二页
|
国产成人精品一区二区三区在线
|
欧美啪啪网站
|