📄 gsm-dtu-gr47avr.c
字号:
#include "iom32v.h"
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define _SLEEP() asm("sleep")
//****I/O define***************
//GSM
#define gsm_onoff 4 //PC4 O
#define gsm_dtr 4 //PD4 O
#define gsm_dcd 5 //PD4 I
#define gsm_txd 0 //PD0 I
#define gsm_rxd 1 //PD1 O
#define se_sim 7 //PC7 O 0 sim
//date and time
#define time_sda 1 //PC1 I/O
#define time_scl 0 //PC0 O
#define time_inta 2 //PD2 I
//uart data
#define r232_txd 0 //PD0 I
#define r232_rxd 1 //PD1 O
//control
#define power_onoff 5 //PC5 O
#define r232_onoff 6 //PD6 O
#define power_detect 3 //PD4 I
#define run_led 6 //PC6 O
//flash
#define spi_cs 1 //PB1 O
#define spi_rst 3 //PB3 O
//*****************************
//**********************
//变量 常量定义
#define wr_device_add 0x64 //时钟器件地址写命令
#define rd_device_add 0x65 //器件地址读命令
#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_DATA_ACK 0x28
#define MR_SLA_ACK 0x40
#define MR_DATA_ACK 0x50
#define MR_DATA_NAK 0x58
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define Wait() {while(!(TWCR&(1<<TWINT)));}
#define TestAck() (TWSR&0xf8)
#define SetAck() (TWCR|=(1<<TWEA))
#define SetNoAck() (TWCR&=~(1<<TWEA))
#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN))
#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
#define F_READ_STATUS_CMD 0xD7 //STATUS_READ
#define F_WRITE_BUFFER1_CMD 0x84 //write buffer1
#define F_WRITE_BUFFER2_CMD 0x87 //write buffer2
#define F_READ_BUFFER1_CMD 0x54 //READ BUFFER1
#define F_READ_BUFFER2_CMD 0x56 //READ BUFFER2
#define F_WRITE_BUFFER1_TO_Page_CMD 0x83 //write buffer1 to page
#define F_WRITE_BUFFER2_TO_Page_CMD 0x86 //write buffer2 to page
#define F_READ_Page_TO_BUFFER1_CMD 0x53 //read main to buffer1
#define F_READ_Page_TO_BUFFER2_CMD 0x55 //read main to buffer2
#define F_READ_PAGE_CMD 0x52 //directly from main to ram
#define F_BUFFER_NUMBER1 0x01 //
uchar gsm_ok_flag=0; //GSM 响应标志 0 无响应 1 有响应
uchar gsm_init_flag=0; //GSM初始化标志 0 1 成功
uchar data_buffer[116];
const uchar default_info_buffer[116]={'A','V','R','G','S','M',
'0','0','0','0','0','0','0','0','0','0','0',',',
'0','0','0','0','0','0','0','0','0','0','0',',',
'0','0','0','0','0','0','0','0','0','0','0',';',
'C','E','N',
'0','0','0','0','0','0','0','0','0','0','0',',',
'0','0','0','0','0','0','0','0','0','0','0',',',
'0','0','0','0','0','0','0','0','0','0','0',';',
'S','I','M',
'0','0','0','0','0','0','0','0','0','0','0',';',
'S','E','T',
'0','0','9','6','0','0',',','N',',','8',',','1',';','C','O','N','1'
};
//eeprom 存储的仪表读数地址 从地址130 开始, 每组数据需要30字节,共15组堆栈式的缓存
//数据记录的格式:
// 记录时间(6byte)+data1(7byte)+data2(7byte)+data3(7byte)+battstatus(1byte)+20h+20h
const uint meter_data_eeprom_start_addr[15]={
130,160,190,220,250,280,310,340,370,400,
430,460,490,520,550};
uint eeprom_data_addr; //eeprom 数据首地址 从上面的表读出的值,供读写eeprom用
uchar data_save_No; //存放数据顺序,从0,14 当值为15以上时候,则自动变0
uchar need_send_data_No_1=0; //定时发送中心数据顺序
uchar need_send_data_No_2=0;
uchar need_send_data_No_3=0;
uchar need_send_data_No_4=0;
uchar need_send_data_No_5=0;
uchar need_send_data_No_6=0;
//
uchar data_from_eeprom[120]; //从EEPROM 读出四个30字节的数据缓存。为定点发送数据到中心用。
uchar need_send_data_No[26]; //
uchar eeprom_data_addr_No;
uchar info_buffer[200]; //接收短信的内容 从86开始
uchar data_temp_buffer[200]; //从内存中读出4个30字节数据保存临时缓冲
uchar data_temp_buffer1[200]; //把二进制转换为ASCII后存储临时缓冲
uchar data_temp_buffer2[200]; //
//uchar data_temp_buffer3[200]; //
ready_cen2_data_1[135];
ready_cen2_data_2[135];
ready_cen2_data_3[135];
uchar data_temp;
uchar info_lenght=0x00; //接收信息的长度
uchar data_length=0x00;
uchar data_lengh_temp;
uchar gsm_send_length=0x00; //发送短信字符内容个数
uchar time_reg;
uchar info_gsm_rx_flag=0; //接收短信成功标志 1 成功
uchar info_meter_rx_flag=0; //接收外部仪表信息标志 1 成功
const uchar default_time[14]={'2','0','0','8','0','8','0','8','0','8','0','8','0','8'};
uchar now_time[12];
uchar now_time_hex[6];
uchar gsm_rx_time[17]; //接收短信时间 08/07/22,00:55:45
uchar rx_mobile_num[11]={'1','3','8','0','0','1','3','8','0','0','0'}; //收短信目标手机号
uchar tx_mobile_num[11]={'1','3','8','0','0','1','3','8','0','0','0'}; //发短信目标手机号
//参数缓存
uchar mas_mobile_num[33]; //管理员手机号(从EEPROM读出临时用)
uchar cen_mobile_num[33];// 数据中心手机号(从EEPROM读出临时用)
uchar me_mobile_num[11]; //本模块使用的SIM号(从EEPROM读出临时用)
uchar baut_rate_num[6]; //波特率 009600,
uchar n_o_e_flag; //N, O , E
uchar uart_byte_num; //8,7
uchar uart_stop_num; //1,2
uchar me_now_status; //1,0 本模块通讯状态 1 常开 0 定时
uchar batt_status; //电池状态 0 正常 1低压
uchar checksum ; //校验和
uint delay_num; //延时常数 ,用于GD& 50us*delay_num
uchar data_save_sequence_num;
//eeprom参数设置内容AVRGSM......CON1 共116个字符保存在EEPROM内容中0x05开始的
//eeprom参数有无设置标志,EEPROM中,0x02 (0xd9表示设置过,否则表示没设置过)
//eeprom存放数据顺序是在0x03 内容为0~14, 如果是其它值则马上写为0。
//外部仪表数据缓存
uchar meter_rx_a_buffer1[7];
uchar meter_rx_a_buffer2[7];
uchar meter_rx_a_buffer3[7];
///子程序
/*UART0---外部设备 初始化*/
void uart_out_init(void)
{
UCSRB=0xd8; //11011000 接收和发送中断,接收和发送使能
UBRRL=23 ;// 23 9600 //(fosc/16/(baud+1))%256;
UBRRH=0x00 ; // (fosc/16/(baud+1))/256;
UCSRC=0x86 ; //
}
/* 延时us 子程序 */
void delay_us(int time) //us delay
{
do
{
time--;
}
while (time>1);
}
/*延时ms子程序 ms delay */
void delay_ms(unsigned int time)
{
while(time!=0)
{
WDR();
delay_us(500);
time--;
}
}
//iic 初始化
void iic_init(void)
{
TWSR=00;
TWBR=0x16; //50K
}
//I/O口方向初始化
void io_init(void)
{
DDRA=0x00;
DDRB=0xCA;
DDRC=0xF1;
DDRD=0x52;
}
//内部EEPROM操作子程序
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
/* 等待上一次写操作结束*/
while(EECR & (1<<EEWE));
/* 设置地址和数据寄存器*/
EEAR = uiAddress;
EEDR = ucData;
/* 置位EEMWE */
EECR |= (1<<EEMWE);
/* 置位EEWE 以启动写操作E */
EECR |= (1<<EEWE);
}
unsigned char EEPROM_read(unsigned int uiAddress)
{/* 等待上一次写操作结束*/
while(EECR & (1<<EEWE))
;
/* 设置地址寄存器*/
EEAR = uiAddress;
/* 设置EERE 以启动读操作*/
EECR |= (1<<EERE);
/* 自数据寄存器返回数据*/
return EEDR;
}
//外部
void USART0_Transmit( unsigned char data )
{
/* 等待发送缓冲器为空*/
PORTC |=(1<<se_sim); //选通
delay_us(100);
do
{
WDR();
}
while ( !( UCSRA & (1<<UDRE)) );
/* 将数据放入缓冲器,发送数据*/
UDR = data;
}
//GSM
void USART1_Transmit( unsigned char data )
{
/* 等待发送缓冲器为空*/
PORTC &=~(1<<se_sim); //选通
delay_us(100);
do
{
WDR();
}
while ( !( UCSRA & (1<<UDRE)) );
/* 将数据放入缓冲器,发送数据*/
UDR = data;
}
//关闭看门狗
void WDT_off(void)
{
/* 置位WDCE 和WDE */
WDTCR = (1<<WDCE) | (1<<WDE);
/* 关闭WDT */
WDTCR = 0x00;
}
//SPI 初始化
void spi_init(void)
{
SPCR=0x51; //
SPSR=0x00; //
}
/******************************************
I2C总线写一个字节
返回0:写成功
返回非0:写失败
*******************************************/
unsigned char i2c_Write(unsigned char Wdata,unsigned int RomAddress)
{
Start();//I2C启动
Wait();
if(TestAck()!=START) return 1;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK) return 1;//ACK
Write8Bit(RomAddress);//写地址
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Write8Bit(Wdata);//写数据
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Stop();//I2C停止
WDR();
delay_ms(10);//延时等EEPROM写完
return 0;
}
/******************************************
I2C总线读一个字节
如果读失败也返回0
*******************************************/
unsigned char i2c_Read(unsigned int RomAddress)
{
unsigned char temp;
Start();//I2C启动
Wait();
if (TestAck()!=START) return 0;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK) return 0;//ACK
// P--;
Write8Bit(RomAddress);//写地址
Wait();
if (TestAck()!=MT_DATA_ACK) return 0;
Start();//I2C重新启动
Wait();
if (TestAck()!=RE_START) return 0;
Write8Bit(rd_device_add);//写I2C从器件地址和读方式
Wait();
if(TestAck()!=MR_SLA_ACK) return 0;//ACK
Twi();//启动主I2C读方式
Wait();
if(TestAck()!=MR_DATA_NAK) return 0;//ACK
temp=TWDR;//读取I2C接收数据
Stop();//I2C停止
WDR();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -