c语言485通信函数 c# 485教程

如何用c语言实现485通信(用485芯片)

就像平时使用串口收发数据一样,没有多大差别!485只是一个硬件规范,与软件无关。在实际编程时只是要考虑使用的设么器件,在收发数据时是否要设定数据方向(如MAX485),或者不需要(MAX488)。

黄岩ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!

您好,有没有关于单片机RS485多机通信的c语言程序啊

/*

* 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 //看门狗相关头文件

#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); //接收与发送使能,接收与接收结束中断使能

UCSRC=_BV(UCSZ1)|_BV(UCSZ0)|_BV(UPM1)|_BV(URSEL); //8位数据位、1位停止位、偶校验

UBRRL=(F_CPU/BAUD/16-1)%256; //设置波特率

UBRRH=(F_CPU/BAUD/16-1)/256;

}

//单字符发送

void Send_Char(char c)

{

while(!(UCSRA_BV(UDRE))); //判断数据寄存器是否为空

UDR=c;

while(!(UCSRA_BV(TXC))); //判断发送是否结束

UCSRA|=_BV(TXC); //通过置位进行手动清零

}

//串口接收部分

//#define RX_BUFFER_SIZE 2

//uchar rx_buffer[RX_BUFFER_SIZE];

//uchar rx_counter;

//uchar Uart_RecvFlag;

//系统初始化

void System_Init()

{

ADCSRA=0xE6; //10位ADC转换置位,启动转换,64分频

DDRB|=_BV(PB0); //485的收发模式控制端口,低电平为接收模式,高电平为发送模式

PORTB=~_BV(PB0);

DDRC=~_BV(PC0); //ADC0引脚定义

PORTC=~_BV(PC0);

TCCR1B=0x03; //T1预设分频: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中断低电平触发

GICR=0XC0; //INT0中断使能

DDRD=~_BV(PD3); //INT1中断引脚定义

PORTD|=_BV(PD3);

// EICRA=0x00; //INT1中断低电平触发

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进行模数转换

//------------------------------------------------------------

INT16U ADC_Convert(void)

{

INT16U Result;

ADMUX=0xC0; //ADC0通道,使用内部参考电压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,关键点

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中断函数

//--------------------------

ISR(INT1_vect)

{

PORTC=~_BV(PC4);

TIMSK=0X00;

}

//--------------------------

//INT0中断函数,用来校正参考电压

//--------------------------

ISR(INT0_vect)

{

//校正参考电压,要用标准2.200V电压来校正

INT16U ADC_C;

ADCSRA=0xE6; //10位ADC转换置位,启动转换,64分频

ADMUX=0xC0; //ADC0通道,使用内部参考电压1.1V

ADC_C=(INT16U)(ADCL+(ADCH8));

ADC_Ref=4035.0/(ADC_C/1024.0*83.0/68.0+1); //要用标准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中断程序负责喂狗(1.9S以内)

//-------------------------------

ISR(TIMER1_OVF_vect)

{

TCNT1=65536-F_CPU/64.0*1.5; //重装初值

wdt_reset(); //看门狗复位

}

//USART串口通信接收中断函数

ISR(USART_RXC_vect)

{

INT8U data;

data=UDR;

sei(); //开总中断,实现中断嵌套

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);

}

关于怎样用c语言写一个基于RS485的通信协议

协议你大概写不出来,按照485的通信规则来把,上网查查资料,用max485芯片就可以了

C语言单片机与485通讯协议

无论是232还是485通讯协议,单片机中都是使用串口通讯实现,唯一不同的是,由于485是半双工通讯,485通讯中要有方向控制。


当前文章:c语言485通信函数 c# 485教程
当前地址:http://ybzwz.com/article/dodjoed.html