?? pc_control_v1.c
字號:
/************************************************************
AVR單片機串口控制應用程序
主要功能:應用PC機串口控制交流電源插座或者照明燈等電器的開關
日期:2004-10-20
作者:肖 鵬 email:www.527dz.com
主頁:www.527dz.com
版本:V1.2 2004-10-30
增加了鍵盤控制電路,同時單片機回送的狀態改為直接讀取I/O電平確定
************************************************************/
#include <iom8v.h>
#include <macros.h>
#include "Io_define.h"
unsigned char RX_data[4]={0}; //串口接收的數據
unsigned char keyb_state=0;
unsigned char keyc_state=0;
unsigned char RX_counter=0; //串口接收到的字節數計數器
void UART_init (void);
void putchar (unsigned char c);
void puts (unsigned char *s);
void UART_rx (void);
void delay_nms (unsigned int n);
void Key_control (unsigned char comm);
void Read_Pin (void);
void putchar(unsigned char c) //字符輸出函數
{
while (!(UCSRA&(1 << UDRE))); //判斷上次發送有沒有完成
UDR = c;
}
#pragma interrupt_handler UART_rx: iv_USART_RX
void UART_rx(void) //串口接收中斷函數
{
RX_data[RX_counter] = UDR;
if (RX_data[RX_counter]=='s')
{
RX_data[0]=RX_data[RX_counter];
RX_counter=0;
}
RX_counter++; //接收的字節數計數
}
void puts(unsigned char *s) //字符串發送函數
{
while (*s)
{
putchar(*s);
s++;
}
}
void UART_init(void)
{
UCSRB = BIT(RXCIE)| BIT(RXEN) |BIT(TXEN); //允許串口發送和接收,并響應接收完成中斷
UBRR = 51; //時鐘8Mhz,波特率9600
UCSRC = BIT(URSEL)|BIT(UCSZ1)|BIT(UCSZ0); //8位數據+1位stop位
}
void main(void)
{
//unsigned char keyb_state=0;
//unsigned char keyc_state=0;
unsigned char i=0;
OSCCAL=0xa3;
DDRB = 0B11000111; //初始化繼電器控制端口
PORTB = 0B00000000;
DDRC = 0B00111111;
PORTC = 0B00000000;
DDRD = 0B10000000;
PORTD = 0B00000000;
DDRB |= 0b00111000; //初始化鍵盤接口,行為低電平
PORTB&= 0b11000111;
DDRD &= ~0b01111000; //列為高電平
PORTD|= 0b01111000;
DDRD &= ~BIT(2); //設置INT0為輸入,高電平狀態
PORTD |= BIT(2);
GICR |= BIT(INT0); //允許INT0外部低電平中斷
UART_init();
SEI();
while (1)
{
if (RX_counter==4)
{
RX_counter=0;
if (RX_data[3] == 't') //接收到PC機發的狀態請求指令,則發送
{ //控制板的key狀態數據給PC
putchar(0); //控制板地址碼
delay_nms(10);
putchar(keyb_state);
delay_nms(10);
putchar(keyc_state);
delay_nms(10);
putchar('t'); //狀態數據標志位
delay_nms(10);
}
else
if ((RX_data[0] == 's')&&(RX_data[3] == 'p')) //檢驗指令格式是否正確
{
if ((RX_data[1] == 'u') &&(RX_data[2]=='0'))//是否是軟件升級指令
{
//puts("upready");
asm("jmp 0xe00");
}
else
if (RX_data[1]=='0') //地址碼是否正確
{
Key_control(RX_data[2]);
}
}
}
}
}
void Key_control(unsigned char comm)
{
CLI();
switch (comm)
{
case '0': key0 ^= key0_open; break;
case '1': key1 ^= key1_open; break;
case '2': key2 ^= key2_open; break;
case '3': key3 ^= key3_open; break;
case '4': key4 ^= key4_open; break;
case '5': key5 ^= key5_open; break;
case '6': key6 ^= key6_open; break;
case '7': key7 ^= key7_open; break;
case '8': key8 ^= key8_open; break;
case '9': key9 ^= key9_open; break;
case ':': key10 ^= key10_open; break;
case ';': key11 ^= key11_open; break;
case 'a': {
PORTB |= 0B11000111;
PORTC |= 0B00111111;
PORTD |= 0B10000000;
} break;
case 'b': {
PORTB &= 0B00111000;
PORTC &= 0B11000000;
PORTD &= 0B01111111;
} break;
}
Read_Pin();
putchar(0); //發送控制板地址碼和key狀態數據
delay_nms(10);
putchar(keyb_state);
delay_nms(10);
putchar(keyc_state);
delay_nms(10);
putchar('t');
delay_nms(10);
SEI();
}
void Read_Pin(void)
{
asm("nop");
keyb_state = ((PINB & 0B11000111)|((PINC & 0B00110000)>>1)|
((PIND & 0B10000000)>>2));
keyc_state = (PINC & 0B00001111);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -