|
发表于 2010-12-18 14:30:02
|
显示全部楼层
08年写的,现在看起来...需要理一下了
/*
PLC_test.c
receive form pc : addr , out_pin , out_ma1 , out_ma2 , check .
send to pc : addr , in_pin , in_ma , in_vol , check .
PIN 状态使用字节的各个位表示,从低到高位表示 PIN1,PIN2,PIN3,PIN4
ma , vol 用实际数10倍的十进制表示,例如:12.1ma表示为 121
经实验测定250欧负载时,PWM值924对应输出20.0ma,以此作为计算标准。
BY: 12145A1@163.COM
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//=================================================================================================
#define _NOP asm("nop")
#define TRUE 1
#define FALSE 0
#define _SET_BIT(x,b) ( (x) |= 1<<(b) )
#define _CLS_BIT(x,b) ( (x) &= ~( 1<<(b) ) )
//=================================================================================================
#define PWM_REF 914
#define PACK_LENGTH 5
#define PIN_IN_NUM 4
#define ME_ADDR 0X51
#define _IS_ADC_OK bit_is_clear(ADCSRA, ADSC)
#define _START_ADC _SET_BIT(ADCSRA, ADSC)
#define _TXD_H _SET_BIT(PORTD,PD1)
#define _TXD_L _CLS_BIT(PORTD,PD1)
#define _OUT_PIN1_H _SET_BIT(PORTC,PC5)
#define _OUT_PIN1_L _CLS_BIT(PORTC,PC5)
#define _OUT_PIN2_H _SET_BIT(PORTB,PB5)
#define _OUT_PIN2_L _CLS_BIT(PORTB,PB5)
#define _OUT_PIN3_H _SET_BIT(PORTB,PB3)
#define _OUT_PIN3_L _CLS_BIT(PORTB,PB3)
#define _OUT_PIN4_H _SET_BIT(PORTB,PB4)
#define _OUT_PIN4_L _CLS_BIT(PORTB,PB4)
#define _IS_PIN1_H bit_is_set(PINB,PB0)
#define _IS_PIN2_H bit_is_set(PIND,PD7)
#define _IS_PIN3_H bit_is_set(PIND,PD6)
#define _IS_PIN4_H bit_is_set(PIND,PD5)
#define ADDR 0
#define IN_PIN 1
#define IN_MA 2
#define IN_VOL 3
#define CHECK 4
//=================================================================================================
unsigned long sum_dat;
unsigned char num_dat;
unsigned char send_dat[PACK_LENGTH];
unsigned char receive_dat[PACK_LENGTH];
unsigned char time_10ms;
unsigned char receive_ok;
//=================================================================================================
ISR( USART_RX_vect ) // 接受中断
{
static unsigned char uart_length;
if(uart_length && !time_10ms)
{
uart_length = 0;
}
receive_dat[uart_length] = UDR0;
if(receive_dat[0] == ME_ADDR)
{
uart_length++;
if(uart_length == PACK_LENGTH)
{
uart_length = 0;
receive_ok = TRUE;
}
}
time_10ms = 2; // 两次数据间隔允许时间
}
//=================================================================================================
ISR(USART_TX_vect ) // 发送中断
{
static unsigned char length;
length ++;
if(length < PACK_LENGTH)
{
UDR0 = send_dat[length];
}
else
{
length = 0;
}
}
//=================================================================================================
// 比较匹配A 产生定时中断10MS
ISR( TIMER0_COMPA_vect )
{
static unsigned char pin_delay[PIN_IN_NUM];
unsigned char ss_pin;
unsigned char n;
/*static unsigned char ff;
ff++;
if(ff == 40)
{
_TXD_L;
}
else if(ff > 80)
{
ff = 0;
_TXD_H;
}
*/
//-----------------------------------------------
if(time_10ms)
{
time_10ms--;
}
//-----------------------------------------------
sei();
//-----------------------------------------------
ss_pin = 0;
if(_IS_PIN1_H) ss_pin |= 0x80;
ss_pin >>= 1;
if(_IS_PIN2_H) ss_pin |= 0x80;
ss_pin >>= 1;
if(_IS_PIN3_H) ss_pin |= 0x80;
ss_pin >>= 1;
if(_IS_PIN4_H) ss_pin |= 0x80;
ss_pin >>= 4;
for(n=0; n<PIN_IN_NUM; n++)
{
if((ss_pin >> n) & 0x01)
{
pin_delay[n]++;
if(pin_delay[n] > 3) // 防抖时间
{
_SET_BIT( send_dat[IN_PIN], n );
}
}
else
{
pin_delay[n] = 0;
_CLS_BIT( send_dat[IN_PIN], n );
}
}
//-----------------------------------------------
}
//=================================================================================================
void refresh_out(void)
{
unsigned int long reg;
if(receive_dat[1] & 1)
{
_OUT_PIN1_H;
}
else
{
_OUT_PIN1_L;
}
if(receive_dat[1] & 2)
{
_OUT_PIN2_H;
}
else
{
_OUT_PIN2_L;
}
if(receive_dat[1] & 4)
{
_OUT_PIN3_H;
}
else
{
_OUT_PIN3_L;
}
if(receive_dat[1] & 8)
{
_OUT_PIN4_H;
}
else
{
_OUT_PIN4_L;
}
if(receive_dat[2] > 200) // 200 即 20.0mA
{
receive_dat[2] = 200;
}
reg = (unsigned long) receive_dat[2] * PWM_REF / 200;
OCR1A = (unsigned int)reg;
if(receive_dat[3] > 200)
{
receive_dat[3] = 200;
}
reg = (unsigned long) receive_dat[3] * PWM_REF / 200;
OCR1B = (unsigned int)reg;
}
//=================================================================================================
unsigned char check_dat(void)
{
//unsigned char sum;
/*sum = 0;
for(n=0; n<uart_length-1; n++)
{
sum += receive_dat[n];
}*/
//sum = receive_dat[0];
if(receive_dat[0] == receive_dat[PACK_LENGTH-1])
{
return TRUE;
}
else
{
return FALSE;
}
}
//=================================================================================================
void init_devices(void)
{
cli();
PORTB = 0X01; // 0000 0001
DDRB = 0XFE; // 1111 1110
PORTC = 0XDC; // 1101 1100
DDRC = 0X20; // 0010 0000
PORTD = 0Xff; // 1111 1111
DDRD = 0X02; // 0000 0010
// ANA----------------------------------
ACSR = 0X80; // 禁止比较器
// ADC----------------------------------
ADMUX = 0X60; // 数据左对齐
ADCSRA = 0x96; // 1001 0110 使能ADC,禁止中断(写1清零),11.0592/64=172.8KHZ
_START_ADC;
while(!_IS_ADC_OK); // 首次转换,初始AD
// PWM1----------------------------------
TCNT1 = 0;
OCR1A = (unsigned int) 40 * PWM_REF / 200; // 默认输出4.0mA
OCR1B = OCR1A;
TCCR1A = 0xa3; // 1010 0011 匹配置位,10位pwm
TCCR1B = 0x0a; // 0000 1010 8分频
// timer0------------------------------
TCCR0A = 0x02; // 0000 0010 CTC 模式
TCCR0B = 0x05; // 0000 0101 1024分频 11.0592/1024=92.6us
OCR0A = 108; // 定时 10000us / 92.6 = 108
TIMSK0 |= 1 << OCIE0A; // 开比较匹配A中断
TIFR0 |= 0X0E; // 0000 1110 清零中断标志
// UART---------------------------------
UCSR0B = 0xD8; // 1101 1000 允许中断,使能接受 和 发送
UCSR0C = 0x06; // 0000 0110 8 bit data
UBRR0H = 0x00; // 波特率高位
UBRR0L = 0x47; // 9600bps 波特率低位
UCSR0A = 0XE0; // 1110 0000
sei();
}
//=================================================================================================
int main(void)
{
init_devices();
_delay_ms(200);
send_dat[0] = ME_ADDR;
send_dat[4] = ME_ADDR;
UDR0 = send_dat[0];
_START_ADC;
while(1)
{
//-----------------------------------------------
if(_IS_ADC_OK)
{
sum_dat += ADCH;
num_dat ++;
if(num_dat == 8)
{
sum_dat /= num_dat;
if(ADMUX == 0X60)
{
ADMUX = 0X61; // 通道1
sum_dat = (sum_dat * 5 * 10000) / 255;
send_dat[IN_MA] = (unsigned int)sum_dat / 250; // 换为mA
}
else
{
ADMUX = 0X60; // 通道0
sum_dat = (sum_dat * 2 * 5 * 10) / 255;
send_dat[IN_VOL] = (unsigned int)sum_dat;
}
sum_dat = 0;
num_dat = 0;
}
_START_ADC;
}
//-----------------------------------------------
if(receive_ok)
{
receive_ok = FALSE;
if( check_dat() )
{
refresh_out();
send_dat[0] = ME_ADDR;
send_dat[4] = ME_ADDR;
UDR0 = send_dat[0];
}
}
//-----------------------------------------------
}
//-----------------------------------------------
} |
|