?? adc_sram.c
字號(hào):
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <inttypes.h>
#include "adc_sram.h"
#include "macro.h"
//全局變量/////////////////////////////
extern uint8_t global_sample_mode_flag;//采樣方式標(biāo)志:手動(dòng)或自動(dòng)
extern uint16_t global_ad_counter;//AD轉(zhuǎn)換計(jì)數(shù)器
extern uint8_t global_operation_detected_flag;//檢測(cè)到動(dòng)作標(biāo)志
uint8_t global_channel_flag;//通道標(biāo)志
extern uint16_t global_close_counter;//合閘線圈地址計(jì)數(shù)器
extern uint16_t global_trip_counter;//分閘線圈地址計(jì)數(shù)器
extern uint16_t global_motor_counter;//打壓電機(jī)地址計(jì)數(shù)器
extern uint16_t global_voltage_counter;//操作電壓地址計(jì)數(shù)器
extern uint8_t global_ad_finish_flag;//AD轉(zhuǎn)換結(jié)束標(biāo)志
//AD板子的初始化,包括端口方向,串口初始化等
void INITIATION(void)
{
DDRC=0xFF;//端口C輸出
PORTC=0xFF;
DDRF|=0x0F;//端口F輸出
sbi(DDRB,2);//CONVST初始化,輸出
sbi(PORTB,2);
sbi(DDRG,0);//WR初始化,輸出1
sbi(PORTG,0);
sbi(DDRG,1);//RD初始化,輸出1
sbi(PORTG,1);
sbi(DDRG,2);//ALE初始化,輸出1
sbi(PORTG,2);
sbi(DDRD,5);//CS_ADC初始化,輸出1
sbi(PORTD,5);
sbi(DDRD,6);//CS_RAM初始化,輸出1
sbi(PORTD,6);
UART_SETTING(19200,7372800);//串口初始化
sbi(DDRE,2);//串口接收控制
cbi(PORTE,2);
}
//延時(shí)程序
void delay_ms(void)
{
uint8_t i;
for(i=0;i<0x01;i++){;}
}
//開外部中斷
void EXTERN_INTERRUPT_OPEN(uint8_t index)
{
EICRA=0xAA;
EICRB=0xAA;//設(shè)置下降沿觸發(fā)
sbi(EIMSK,index);
sbi(SREG,7);//將寄存器SREG的“I”置1
}
//關(guān)外部中斷
void EXTERN_INTERRUPT_CLOSE(uint8_t index)
{
cbi(EIMSK,index);
// sbi(SREG,7);//將寄存器SREG的“I”置1
}
//SRAM寫操作
void SRAM_1M_8_WRITE(uint32_t address,uint8_t data)
{
//變量定義
// uint8_t addr_l,addr_m,addr_h;
//
cbi(PORTD,6);//ram片選拉低
sbi(PORTD,5);//AD片選拉高
DDRA=0xFF;//a口輸出
// addr_h=(address>>16);//高4位地址
// addr_h=(addr_h&0x0F);
// addr_m=(address>>8);//中間8位地址
// addr_l=address;//低8位地址
// PORTA=addr_l;//寫ram地址
// PORTC=addr_m;
// PORTF&=0xF0;//低4位清零
// PORTF|=addr_h;
PORTA=address;//低8位地址
PORTC=(address>>8);//中間8位地址
PORTF&=0xF0;//低4位清零
PORTF|=(address>>16)&0x0F;
cbi(PORTG,2);//地址鎖存
PORTA=data;//將數(shù)據(jù)放在總線上
cbi(PORTG,0);//寫拉低
delay_ms();//延時(shí)//////////////////
sbi(PORTG,0);//寫拉高
sbi(PORTG,2);//去鎖存
}
//SRAM讀操作
uint8_t SRAM_1M_8_READ(uint32_t address)
{
uint8_t addr_l,addr_m,addr_h,temp;
cbi(PORTD,6);//ram片選拉低
sbi(PORTD,5);//AD片選拉高
DDRA=0xFF;//a口輸出
addr_l=address;//低8位地址
addr_m=(address>>8);//中間8位地址
addr_h=(address>>16);//高4位地址
addr_h=(addr_h&0x0F);
PORTA=addr_l;//輸出ram地址
PORTC=addr_m;
PORTF&=0xF0;//低4位清零
PORTF|=addr_h;
cbi(PORTG,2);//地址鎖存
cbi(PORTG,1);//讀拉低
delay_ms();//延時(shí)//////////////////
DDRA=0x00;//a口輸入
PORTA=0xFF;//設(shè)置上拉
temp=PINA;//讀取總線上的數(shù)據(jù)
sbi(PORTG,1);//讀拉高
sbi(PORTG,2);//去鎖存
sbi(PORTD,6);//去掉片選信號(hào)
return temp;
}
//AD寫操作
void AD7891_WRITE(uint16_t cmd)
{
//CS:PD5;WR:PG0;RD:PG1
//DATA0~DATA7:PORTA
//ADCD8~ADCD11:PB4~PB7
uint8_t addr_h;
DDRA=0xFF;//a口輸出
DDRB|=0xF0;//端口B高4位輸出
// addr_l=cmd;
addr_h=(cmd>>8);
addr_h=(addr_h<<4);//低4位移動(dòng)到高位
addr_h&=0xF0;//取高4位
//片選
cbi(PORTD,5);//ad片選拉低
sbi(PORTD,6);//ram片選拉高
PORTA=cmd;
PORTB&=0x0F;//高4位清零
PORTB|=addr_h;
cbi(PORTG,0);//寫拉低
delay_ms();
sbi(PORTG,0);//寫拉高
}
//AD讀操作,返回一16位整數(shù)
uint16_t AD7891_READ(void)
{
//CS:PD5;WR:PG0;RD:PG1
//DATA0~DATA7:PORTA
//ADCD8~ADCD11:PB4~PB7
uint8_t result_l,result_h;
uint16_t result;
////////設(shè)置端口方向////////////////
DDRA=0x00;//PORTA as input
PORTA=0xFF;//設(shè)置上拉
DDRB&=0x0F;//PB4~PB7 as input
PORTB|=0xF0;//PB4~PB7設(shè)置上拉
////////讀///////////////////////////
//片選
cbi(PORTD,5);//ad片選拉低
sbi(PORTD,6);//ram片選拉高
cbi(PORTG,1);//讀拉低
delay_ms();
result_l=PINA;
result_h=PINB;
result_h&=0xF0;
result=result_h;
result=result<<4;
result|=result_l;
sbi(PORTG,1);//讀拉高
return result;
}
//AD通道選擇,index:1~8
void AD7891_CHANNEL_SELECT(uint16_t index)
{
index--;//0~7
index=(index<<3);
index&=0x38;//00111000,保留A2、A1、A0,將其它位屏蔽
AD7891_WRITE(index);
}
//AD轉(zhuǎn)換開始
void AD7891_CONVERSION_START(void)
{
cbi(PORTB,2);//拉低CONVST
delay_ms();
sbi(PORTB,2);//拉高CONVST,啟動(dòng)AD轉(zhuǎn)換
}
//串口初始化設(shè)置,包括設(shè)置波特率、8位數(shù)據(jù)+1位STOP位、多機(jī)通訊模式設(shè)置
void UART_SETTING(int baud_rate, long fosc)
{
UBRR0L=(fosc/16/(baud_rate+1))%256;//設(shè)置波特率
UBRR0H=(fosc/16/(baud_rate+1))/256;
UCSR0A|=(1<<MPCM0);//多機(jī)通訊模式
// UCSR0B|=(1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);//允許發(fā)送和接收,并允許接收中斷
UCSR0C|=(1<<UCSZ01)|(1<<UCSZ00);//9位數(shù)據(jù)+1位STOP位,從機(jī)
UCSR0B|=(1<<UCSZ02);
}
//開串口接收中斷
void UART_RXCINT_OPEN(void)
{
UCSR0B|=(1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);//允許發(fā)送和接收,并允許接收中斷
}
//關(guān)串口接收中斷
void UART_RXCINT_CLOSE(void)
{
UCSR0B&=~(1<<RXCIE0);
}
//發(fā)送單字節(jié)
void UART_DATA_BYTE_SEND(uint8_t data)
{
uint8_t i;
sbi(PORTE,2);//改為發(fā)送狀態(tài)
//延時(shí)等待
for(i=0;i<0xff;i++){;}
//等待UDRE被置位,否則對(duì)數(shù)據(jù)寄存器UDR的寫操作將被忽略
if(!(UCSR0A&(1<<UDRE0)))
{
UCSR0A|=(1<<UDRE0);
}
//等待發(fā)送緩沖器空
while(!(UCSR0A&(1<<UDRE0))){;}
UDR0=data;//發(fā)送數(shù)據(jù)
loop_until_bit_is_set(UCSR0A,TXC0);//查詢發(fā)送是否結(jié)束
UCSR0A=UCSR0A|(1<<TXC0);//因?yàn)闆](méi)有使用發(fā)送結(jié)束中斷,所以通過(guò)置數(shù)將TXC清零
cbi(PORTE,2);//改為接收狀態(tài)
}
//發(fā)送一包數(shù)據(jù),temp_data為包序號(hào),從1開始編號(hào)
void SEND_ONE_PACKAGE(uint8_t temp_data)
{
//變量定義
uint8_t crc16,temp_array[512];
uint16_t i;
uint32_t address;
//校驗(yàn)碼初始化
crc16=0;
crc16=crc16+2+temp_data;//加入地址和包序號(hào)校驗(yàn)
//根據(jù)包序號(hào)獲得相應(yīng)的數(shù)據(jù),包序號(hào)從1開始編號(hào)
//合閘線圈電流數(shù)據(jù)地址
if((temp_data>=1)&&(temp_data<=8)){address=(temp_data-1)*512;}
//分閘線圈電流數(shù)據(jù)地址
if((temp_data>=9)&&(temp_data<=16)){address=(temp_data-8-1)*512+10000;}
//電機(jī)電流數(shù)據(jù)地址
if((temp_data>=17)&&(temp_data<=24)){address=(temp_data-16-1)*512+30000;}
//操作電壓數(shù)據(jù)地址
if((temp_data>=25)&&(temp_data<=32)){address=(temp_data-24-1)*512+20000;}
//根據(jù)地址給要發(fā)送的一個(gè)數(shù)組的數(shù)據(jù)和校驗(yàn)碼賦值
for(i=0;i<512;i++)
{
temp_array[i]=SRAM_1M_8_READ(address+i);//讀取數(shù)據(jù)
crc16+=temp_array[i];//累加校驗(yàn)碼
}
//發(fā)送數(shù)據(jù)包
UART_DATA_BYTE_SEND(2);//發(fā)送地址
UART_DATA_BYTE_SEND(temp_data);//發(fā)送包序號(hào)
for(i=0;i<512;i++)//發(fā)送512字節(jié)數(shù)據(jù)
{
UART_DATA_BYTE_SEND(temp_array[i]);
}
UART_DATA_BYTE_SEND(crc16);//發(fā)送校驗(yàn)碼
}
//設(shè)定采樣周期,定時(shí)器開始記數(shù)
void TIMER_BEGIN(void)
{
//預(yù)分頻8
TCCR1B&=0xF8;//11111 000
TCCR1B|=0x02;//00000 010
//選擇快速PWM模式
TCCR1B|=(1<<WGM12)|(1<<WGM13);
TCCR1A|=3<<WGM10;
//輸出比較寄存器,按照晶振7.3728MM,采樣頻率8K
// OCR1A=115;//(1/7.3728M)*(預(yù)分頻)*TOP=1/8K
// OCR1A=40;//(1/7.3728M)*(預(yù)分頻)*TOP=1/16K
// OCR1A=230;//(1/7.3728M)*(預(yù)分頻)*TOP=1/4K
// OCR1A=307;//(1/7.3728M)*(預(yù)分頻)*TOP=1/3K
OCR1A=10;//測(cè)試用
}
//定時(shí)器結(jié)束計(jì)時(shí)
void TIMER_STOP(void)
{
//將預(yù)分頻置0,終止定時(shí)器
TCCR1B&=0xF8;//1111 1000
}
//數(shù)據(jù)采集程序
void SAMPLE(void)
{
//變量定義
uint16_t test_counter=0;
uint16_t int16_temp;
uint16_t i;
//全局變量初始化
global_ad_counter=0;//采樣計(jì)數(shù)器清零
global_channel_flag=0;//采樣通道清零
global_close_counter=0;//合閘線圈地址計(jì)數(shù)器
global_trip_counter=10000;//分閘線圈地址計(jì)數(shù)器
// global_motor_counter=20000;//打壓電機(jī)地址計(jì)數(shù)器
global_voltage_counter=20000;//操作電壓地址計(jì)數(shù)器
//啟動(dòng)定時(shí)器,采樣周期在這里設(shè)置
// TIMER_BEGIN();
//當(dāng)采樣個(gè)數(shù)不足時(shí),進(jìn)行此循環(huán)
while(global_ad_counter<6000)//6000
// while(global_ad_counter<12000)//6000
{
//AD轉(zhuǎn)換結(jié)束標(biāo)志初始化
global_ad_finish_flag=0;
//選擇采樣通道
if(global_channel_flag==3){global_channel_flag=1;}
else{global_channel_flag++;}
if(global_channel_flag==3)
{
AD7891_CHANNEL_SELECT(4);
}
else
{
AD7891_CHANNEL_SELECT(global_channel_flag);
}
//啟動(dòng)AD轉(zhuǎn)換
AD7891_CONVERSION_START();
//等待AD轉(zhuǎn)換結(jié)束標(biāo)志被賦值
while(global_ad_finish_flag!=0xFF){;}
//延時(shí)
for(i=0;i<7;i++)
{
;
}
PORTG^=0x08;//測(cè)試用???????????
//等待定時(shí)器溢出,AD結(jié)束中斷處理在等待過(guò)程中完成
// while(!(TIFR&(1<<OCF1A))){;}
// TIFR|=1<<OCF1A;
//選中AD(因?yàn)樵贏D中斷里去掉了AD的片選)
cbi(PORTD,5);
}
//AD計(jì)數(shù)清零
global_ad_counter=0;
//終止定時(shí)器
// TIMER_STOP();
//AD片選去掉
cbi(PORTD,5);
}
//檢測(cè)動(dòng)作是否開始程序
uint8_t OPERATION_DETECTION(void)
{
//變量定義
uint16_t int16_temp;
//采樣計(jì)數(shù)器清零
global_ad_counter=0;
//檢測(cè)到動(dòng)作標(biāo)志清零
global_operation_detected_flag=0;
//啟動(dòng)定時(shí)器,采樣周期在這里設(shè)置
// TIMER_BEGIN();
//當(dāng)沒(méi)有檢測(cè)到動(dòng)作時(shí),進(jìn)行此循環(huán)
while(global_operation_detected_flag==0)
{
//AD轉(zhuǎn)換結(jié)束標(biāo)志初始化
global_ad_finish_flag=0;
//選擇采樣通道
int16_temp=global_ad_counter%2;
//通道1為合閘線圈電流
if(int16_temp==0){AD7891_CHANNEL_SELECT(1);}
//通道2為分閘線圈電流
if(int16_temp==1){AD7891_CHANNEL_SELECT(2);}
//啟動(dòng)定時(shí)器,采樣周期在這里設(shè)置
// TIMER_BEGIN();
//啟動(dòng)AD轉(zhuǎn)換
AD7891_CONVERSION_START();
//等待AD轉(zhuǎn)換結(jié)束標(biāo)志被賦值
while(global_ad_finish_flag!=0xFF){;}
//等待定時(shí)器溢出,AD結(jié)束中斷處理在等待過(guò)程中完成
// while(!(TIFR&(1<<OCF1A))){;}
// TIFR|=1<<OCF1A;
//選中AD(因?yàn)樵贏D中斷里去掉了AD的片選)
cbi(PORTD,5);
}
//如果檢測(cè)到了動(dòng)作開始
//向主機(jī)發(fā)送自動(dòng)測(cè)試開始命令0x33
// UART_DATA_BYTE_SEND(0x33);
//AD計(jì)數(shù)清零
global_ad_counter=0;
//終止定時(shí)器
// TIMER_STOP();
//AD片選去掉
cbi(PORTD,5);
//檢測(cè)到動(dòng)作標(biāo)志清零
global_operation_detected_flag=0;
//自動(dòng)測(cè)試標(biāo)志復(fù)原
global_sample_mode_flag=0xFF;
}
/*TIMER test//////////////////
//數(shù)據(jù)采集程序
void SAMPLE(void)
{
uint16_t count=0;//采樣個(gè)數(shù)
//開外部中斷7(AD轉(zhuǎn)換結(jié)束中斷)
// EXTERN_INTERRUPT_OPEN(7);
sbi(DDRE,3);
sbi(PORTE,3);
//啟動(dòng)定時(shí)器,采樣周期0.5ms
TIMER_BEGIN();
// while(count<SAMPLE_NUMBER)//當(dāng)采樣個(gè)數(shù)不足時(shí),進(jìn)行此循環(huán)
while(1)//
{
//采樣記數(shù)加1
count++;//放在這里,不影響采樣間隔
PORTE=~PORTE;
//啟動(dòng)AD轉(zhuǎn)換
//???
//等待定時(shí)器溢出
while(!(TIFR&(1<<TOV1))){;}
}
//終止定時(shí)器
TIMER_STOP();
}
*/
/*
//數(shù)據(jù)采集00000,00001存放數(shù)據(jù)個(gè)數(shù)
//1通道:00010H~1FFFFH
//2通道:20000H~3FFFFH
//3通道:40000H~5FFFFH
//4通道:60000H~7FFFFH
//5通道:80000H~9FFFFH
//6通道:A0000H~BFFFFH
//7通道:C0000H~DFFFFH
//8通道
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -