|
楼主 |
发表于 2014-3-14 06:42:45
|
显示全部楼层
C 编写的 文本void initpic()
{
U8 i;
U16 address ;
U8 x;
U8 y;
U16 z;
//清零所有画面标志位*****************************************************
pic_info.has_send = 0;
pic_info.trsmit_over = 0;
pic_info.has_timeout = 0;
pic_info.comm_receive = 1;
pic_info.comm_page = 0; //普通画面上的瞬时on消息
pic_info.keypressed = 0;
pic_info.recvUart0 = 0; //uart0 recv sign used in the timer0
pic_info.recvUart1 = 0;
//清零所有寄存器标志位
reg_info. reg_input = 0; //寄存器输入标记
reg_info. reg_init = 0; //寄存器数据初始化标记
reg_info. button_control = 0; //按钮通讯标记
reg_info. TEST = 0; //0-user program 1-test mode
reg_info. minus_plus = 0; //0,plus 1,minus
reg_info. disp_sign_enable = 0; //enable to display sign,显示正负号标记
reg_info. alarm = 0; //mode at alarm ,0:user mode,1:alarm mode
reg_info. pic_changed = 0; //current pic has changed
//清零所有通讯标志位
com_info.PG_Comm = 0; //如果连接的是pg线,1
com_info. keyin = 0;
com_info. button_decode = 0; //全局按钮解码标记,解码完毕就清除
com_info. pass_req = 0;
com_info. pass_error = 0;
com_info. update_enable = 0; //update=1 才可以进行升级
com_info. screen_scr = 0;
com_info. write_plc = 0; //报告plc
//************************************************************************************
reg_info.pic_changed=1;
current_pic = system_info.first_pic; //指向初始画面
com_num = 0; //上一个画面的通讯指令数目为0,防止进入正常画面切换时影响报警列表通讯结构
part_number = 0; //part_number 通讯块总数
//**************************************************************************************
if(system_info.alarm_num<=8) //防止ram溢出
{
i = system_info.alarm_num; //system_info.alarm_num 报警通讯指令数目
}
address = system_info.alarm_commAdd; //alarm_commAdd 报警列表的通讯指令初始地址
while(i--)
{
comm_struct[part_number].control = 0x1|(*((U8 *) address++)<< 1);//该段通讯的属性 bit0 is alarm sign,bit1 is pg comm port
comm_struct[part_number].str_num = *((U8 *) (address++));//该段通讯指令总数目
comm_struct[part_number].start_address = *((U16*)address);//该段通讯指令的首地址uint
address += 2;
comm_struct[part_number].cur_state = *((U8 *) (address++)); //储存报警列表返回值地址 //当前状态
comm_struct[part_number].comm_pri = 0;//优先级最高 //通讯优先级。0:每次通讯切换通讯一次。10:每10次通讯切换通讯一次
part_number++;
}
if (system_info.rw_plc & 0x1) //有画面号读取功能 //system_info.rw_plc*******1:read plc ******1*:write current pic_num to plc *****1**:clear dst after read
{ /*把system_info.port的第一位送给control的BIT0*/
comm_struct[part_number].control = (system_info.port << 1) & 0x2; /* control 格式如下:*/
// bit0= 1,报警通讯;0,正常通讯
// bit1= 1,uart0 ;0,uart1 通讯
// bit2= 1, 寄存器数值批量读取,在数据发送返回时处理数据到通讯缓存的高位.
// bit3= 1, 寄存器数值批量写入,不需要返回值,在数值传递到缓存区时处理数据和校验 //system_info.port 交互控制的端口,1:pg port 0:485 port comm
comm_struct[part_number].str_num = 1; //该段通讯指令总数目
comm_struct[part_number].start_address = system_info.read_comm_add; //该段通讯指令的首地址uint
comm_struct[part_number].comm_pri = 0;//优先级最高
part_number++;
}
//批量读取寄存器通讯队列初始化
if(system_info.reg_read_num<=3) // system_info.reg_read_num 批量读寄存器通讯块数目
{
i = system_info.reg_read_num; //防止块溢出
}
address = system_info.reg_read_add; //num+n*(comm_ins + add + len)(comm_ins 有校验)
copy_struct.pare_num=0; //???????
while (i--)
{
comm_struct[part_number].control = 0x4|*(((U8 *) (address++)))<< 1;
/* control 格式如下:*/
// bit0= 1,报警通讯;0,正常通讯
// bit1= 1,uart0 ;0,uart1 通讯
// bit2= 1, 寄存器数值批量读取,在数据发送返回时处理数据到通讯缓存的高位.
// bit3= 1, 寄存器数值批量写入,不需要返回值,在数值传递到缓存区时处理数据和校验
comm_struct[part_number].str_num = *((U8 *) (address++));
comm_struct[part_number].start_address = *((U16 *) (address));
address += 2;
comm_struct[part_number].cur_state = *((U8 *) (address++)); //储存在通讯buffer地址(0x80以后)
comm_struct[part_number].len = *((U8 *) (address++)); //返回值的byte长度
comm_struct[part_number].comm_pri = 0;//优先级最高
//判断是否会溢出,如果超出通讯缓冲区高位就不添加该信息.
x=comm_struct[part_number].cur_state;
y=comm_struct[part_number].len;
z=x+y;
if(z>=0x100)
{
continue; //跳出本次循环
}
copy_struct.copy_list[copy_struct.pare_num].s_add=comm_struct[part_number].cur_state; //左值表示源拷贝地址
copy_struct.copy_list[copy_struct.pare_num].enable=0;
copy_struct.pare_num++;
part_number++;
}
//批量写寄存器通讯队列初始化
if(system_info.reg_write_num<=3)
{
i = system_info.reg_write_num; //防止块溢出
}
address = system_info.reg_write_add;
while (i--)
{
comm_struct[part_number].control = 0x8|(*((U8 *) (address++))<< 1); //bit0 is alarm sign,bit1 is pg comm port
comm_struct[part_number].str_num = *((U8 *) (address++));
comm_struct[part_number].start_address = *((U16 *) (address));
address += 2;
comm_struct[part_number].cur_state = *((U8 *) (address++)); //储存在通讯buffer地址(0x80以后)
comm_struct[part_number].len = *((U8 *) (address++)); //返回值的byte长度
comm_struct[part_number].comm_pri = 0;//优先级最高
part_number++;
}
}
int main(void)
{
initpic(); //画面初始化 清零标志位
GPIOinit(); //初始化io口
CLOCKinit(); //初始化系统时钟
UARTinit(); //初始化串口
TIMERinit(); //初始化定时器
Init_Lcd(); //LCD初始化
Clr_Scr(); //清除LCD内存
GPIO_ClrBit(ensr485); //485 在接收模式,transmit=1:发送 transmit=0:接收,1168's control pin
GPIO_SetBit(back_light);//打开液晶背光
GPIO_ClrBit(buzz); //关闭蜂鸣器
GPIO_ClrBit(ensr232); //置232为接收模式
while(1)
{
com_info.update_enable = 0; //清除升级标记,timer0收到升级命令会立马跳到升级程序。
/*通过JUDGE引脚上的电平决定OP10通过RS232与电脑通信还是与PLC通信并进行相应的串口0的设置和波特率设置*/
if(GPIO_GetBit(judge)==1)//如果judge==1则链接的是PLC
{
if(system_info.pg_set&0x03!=0x03||system_info.pg_set&0x04!=0||system_info.pg_set&0x018!=0||system_info.pg_rate!=71)
{ //如果数据位、停止位、校验位、波特率与系统初始化的不同,则重新装载
switch(system_info.pg_set&0x03) //通过232与PLC通讯时的数据位数
{
case 0x00:
UART0->LCR.WLS = 0; //5 data bits
break;
case 0x01:
UART0->LCR.WLS = 1; //6 data bits
break;
case 0x02:
UART0->LCR.WLS = 2; //7 data bits
break;
case 0x03:
UART0->LCR.WLS = 3; //8 data bits
break;
default:
break;
}
switch(system_info.pg_set&0x04)//通过232与PLC通讯时的停止位数
{
case 0x00:
UART0->LCR.NSB = 0; //Enable 1 Stop bit
break;
case 0x04:
UART0->LCR.NSB = 2; //Enable 2 Stop bit
break;
default:
break;
}
switch(system_info.pg_set&0x018)//通过232与PLC通讯时的校验方式
{
case 0x00:
UART0->LCR.PBE = 0; //Disable parity
break;
case 0x08:
UART0->LCR.PBE = 1;//奇偶使能位
UART0->LCR.SPE = 1;//奇偶位传输检测有效
UART0->LCR.EPE = 0;//奇校验
break;
case 0x10:
UART0->LCR.PBE = 1;//奇偶使能位
UART0->LCR.SPE = 1;//奇偶位传输检测有效
UART0->LCR.EPE = 0;//偶校验
break;
default:
break;
}
switch(system_info.pg_rate)//根据上位机数据设置串口1波特率
{
case 143:
|
|