就像平時使用串口收發(fā)數(shù)據(jù)一樣,沒有多大差別!485只是一個硬件規(guī)范,與軟件無關(guān)。在實際編程時只是要考慮使用的設(shè)么器件,在收發(fā)數(shù)據(jù)時是否要設(shè)定數(shù)據(jù)方向(如MAX485),或者不需要(MAX488)。
黃巖ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!
/*
* MEGA8_485_EEPROM_817_ADC_WDT.c
*
* Created: 2013-8-8 16:52:15
* Author: Administrator
*/
#define F_CPU 4000000UL
#include avr/io.h
#include util/delay.h
#include avr/interrupt.h
#include string.h
#include avr/wdt.h //看門狗相關(guān)頭文件
#include avr/eeprom.h
#define INT8U unsigned char
#define INT16U unsigned int
#define INT32U unsigned long
#define BT_NO 0xDE //電池的識別號碼
INT8U eepromx EEMEM;
//全局變量
INT16U ADC_bt_v;
INT8U UART_Send_flag;
INT8U ADC_Buffer[]={0,0,0,0};
static INT32U ADC_bt_Total=0;
INT16U ADC_bt_S;
INT16U ADC_Ref_Buffer[]={0,0};
float ADC_Ref;
INT16U n;
//串口初始化
void Usart_Init(INT16U BAUD)
{
UCSRB =_BV(RXEN)|_BV(TXEN)|_BV(RXCIE); //接收與發(fā)送使能,接收與接收結(jié)束中斷使能
UCSRC=_BV(UCSZ1)|_BV(UCSZ0)|_BV(UPM1)|_BV(URSEL); //8位數(shù)據(jù)位、1位停止位、偶校驗
UBRRL=(F_CPU/BAUD/16-1)%256; //設(shè)置波特率
UBRRH=(F_CPU/BAUD/16-1)/256;
}
//單字符發(fā)送
void Send_Char(char c)
{
while(!(UCSRA_BV(UDRE))); //判斷數(shù)據(jù)寄存器是否為空
UDR=c;
while(!(UCSRA_BV(TXC))); //判斷發(fā)送是否結(jié)束
UCSRA|=_BV(TXC); //通過置位進行手動清零
}
//串口接收部分
//#define RX_BUFFER_SIZE 2
//uchar rx_buffer[RX_BUFFER_SIZE];
//uchar rx_counter;
//uchar Uart_RecvFlag;
//系統(tǒng)初始化
void System_Init()
{
ADCSRA=0xE6; //10位ADC轉(zhuǎn)換置位,啟動轉(zhuǎn)換,64分頻
DDRB|=_BV(PB0); //485的收發(fā)模式控制端口,低電平為接收模式,高電平為發(fā)送模式
PORTB=~_BV(PB0);
DDRC=~_BV(PC0); //ADC0引腳定義
PORTC=~_BV(PC0);
TCCR1B=0x03; //T1預(yù)設(shè)分頻:256
TCNT1=65536-F_CPU/64.0*1.5; //晶振4MHZ,1.5S定時初值
TIMSK=0x04; //允許T1定時器溢出中斷
wdt_enable(WDTO_2S); //啟動看門狗(溢出時間1.9S,約等于2.0S)
/* WDTCSR=0x0F;*/
DDRD=~_BV(PD2); //INT0中斷引腳定義
PORTD|=_BV(PD2);
MCUCR=0x00; //INT0中斷低電平觸發(fā)
GICR=0XC0; //INT0中斷使能
DDRD=~_BV(PD3); //INT1中斷引腳定義
PORTD|=_BV(PD3);
// EICRA=0x00; //INT1中斷低電平觸發(fā)
eeprom_busy_wait();
ADC_Ref_Buffer[0]=(INT16U)eeprom_read_byte(1);
eeprom_busy_wait();
ADC_Ref_Buffer[1]=(INT16U)eeprom_read_byte(2);
ADC_Ref=(float)(ADC_Ref_Buffer[0]*100.0+ADC_Ref_Buffer[1]);
DDRC|=_BV(PC4); //測試引腳
PORTC|=_BV(PC4);
sei(); //開總中斷
}
//------------------------------------------------------------
//對通道CH進行模數(shù)轉(zhuǎn)換
//------------------------------------------------------------
INT16U ADC_Convert(void)
{
INT16U Result;
ADMUX=0xC0; //ADC0通道,使用內(nèi)部參考電壓1.1V
Result=(INT16U)((ADCL+(ADCH8))*ADC_Ref/1024.0*83.0/68.0+ADC_Ref);
return Result;
}
INT16U ADC_T()
{
INT16U ADC_bt;
ADC_bt=ADC_Convert();
ADCSRA=0xE6;
_delay_us(500); //延時后重新再讀取ADC,關(guān)鍵點
ADC_bt=ADC_Convert();
ADCSRA=0xE6;
return ADC_bt;
}
int main(void)
{
Usart_Init(9600);
System_Init();
_delay_ms(1000);
while(1)
{
_delay_ms(10);
}
}
//--------------------------
//外部中斷1中斷函數(shù)
//--------------------------
ISR(INT1_vect)
{
PORTC=~_BV(PC4);
TIMSK=0X00;
}
//--------------------------
//INT0中斷函數(shù),用來校正參考電壓
//--------------------------
ISR(INT0_vect)
{
//校正參考電壓,要用標(biāo)準(zhǔn)2.200V電壓來校正
INT16U ADC_C;
ADCSRA=0xE6; //10位ADC轉(zhuǎn)換置位,啟動轉(zhuǎn)換,64分頻
ADMUX=0xC0; //ADC0通道,使用內(nèi)部參考電壓1.1V
ADC_C=(INT16U)(ADCL+(ADCH8));
ADC_Ref=4035.0/(ADC_C/1024.0*83.0/68.0+1); //要用標(biāo)準(zhǔn)2.200V來校正,精度要盡量高
ADC_Ref_Buffer[0]=ADC_Ref/100;
ADC_Ref_Buffer[1]=(INT16U)ADC_Ref%100;
eeprom_busy_wait();
eeprom_write_byte(1,ADC_Ref_Buffer[0]);
eeprom_busy_wait();
eeprom_write_byte(2,ADC_Ref_Buffer[1]);
}
//-------------------------------
//定時器1中斷程序負責(zé)喂狗(1.9S以內(nèi))
//-------------------------------
ISR(TIMER1_OVF_vect)
{
TCNT1=65536-F_CPU/64.0*1.5; //重裝初值
wdt_reset(); //看門狗復(fù)位
}
//USART串口通信接收中斷函數(shù)
ISR(USART_RXC_vect)
{
INT8U data;
data=UDR;
sei(); //開總中斷,實現(xiàn)中斷嵌套
UCSRB=~_BV(RXCIE);
switch (data)
{
case BT_NO:
for (INT8U n;n8;n++)
{
ADC_bt_S=ADC_T();
ADC_bt_Total=(INT32U)(ADC_bt_Total+ADC_bt_S);
}
ADC_bt_v=(INT16U)(ADC_bt_Total/8.0);
ADC_bt_Total=0;
ADC_Buffer[0]=ADC_bt_v/1000;
ADC_Buffer[1]=ADC_bt_v/100%10;
ADC_Buffer[2]=ADC_bt_v/10%10;
ADC_Buffer[3]=ADC_bt_v%10;
PORTB|=_BV(PB0);
_delay_ms(1);
Send_Char(BT_NO); //表明哪個電池分送的信號
_delay_ms(1);
PORTB=~_BV(PB0);
PORTB|=_BV(PB0);
_delay_ms(1);
Send_Char(ADC_Ref_Buffer[0]); //MCU參考電壓高位
_delay_ms(1);
PORTB=~_BV(PB0);
PORTB|=_BV(PB0);
_delay_ms(1);
Send_Char(ADC_Ref_Buffer[1]); //MCU參考電壓低位
_delay_ms(1);
PORTB=~_BV(PB0);
for (INT8U i=0;i4;i++)
{
PORTB|=_BV(PB0);
_delay_ms(1);
Send_Char(ADC_Buffer[i]);
_delay_ms(1);
PORTB=~_BV(PB0);
}
break;
}
UCSRB|=_BV(RXCIE);
}
協(xié)議你大概寫不出來,按照485的通信規(guī)則來把,上網(wǎng)查查資料,用max485芯片就可以了
無論是232還是485通訊協(xié)議,單片機中都是使用串口通訊實現(xiàn),唯一不同的是,由于485是半雙工通訊,485通訊中要有方向控制。