📄 main.c
字号:
/**
******************************************************************************
* @file STM32_Core_Mode
* @author CSU_maowei
* @version V3.3.0
* @date 11/14/2011
* @brief This file contain can mode , network mode , EEROM and Flash mode.
*****************************************************************************/
#include "spi.h"
#include "can.h"
#include "i2c.h"
#include "usart.h"
#include "server.h"
#include "netconf.h"
#include "stm32f107.h"
#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>
u8 tim_3 = 0; //每秒3次
u8 tim_5 = 0; //每秒5次
u8 tim_25 = 0; //每秒25次
volatile u16 tim_cnt = 0; //定时器计数
u16 TuiziAddr[5] = {0}; //推子模块地址
u16 InputAddr[5] = {0}; //输入模块地址
u16 OutputAddr[5] = {0}; //输出模块地址
u8 InputFlag = 0; //输入模块远程帧标志
u8 OutputFlag = 0; //输出模块远程帧标志
u8 can1_flag = 0; //CAN1中断接收推子模块按键数据标志
u8 startflg1 = 0; //CAN1中断接收推子模块远程帧标志
u8 startmain = 0; //CAN1中断接收总控模块远程帧标志
u8 ManGainData[4] = {32,32,32,32}; //总控模块AD增益值
u8 ADGainData[40] = {0}; //推子模块AD增益值
u8 BindADData[40] = {0}; //增益绑定
//(协议一:0xAA)
//FPGA接收[推子模块电位器增益]后返回的输入信号的DB值
char RxIndBData[40] = {0};
//(协议二:0xAB)
//FPGA接收[上位机设置的输出总线增益与总控模块电位器增益]
//FPGA返回的输出总线的DB值
char RxOutdBData[12]={0};
//(协议四:0xAD)
//FPGA接收[上位机设置的对讲人输入物理地址、对讲键状态、同步设置]
//FPGA返回值(5路输入板信号状态,6路输出总线状态)
u8 RxIOBusState[7]={0};
u8 KeyData[20] = {0}; //5个主控模块,共20路的按键值
u8 KeyDataBK[20] = {0}; //存储原来按键值
u8 KeySPIData[20] = {0}; //处理"高2位代表信号模式(立体声,混合音,左,右声道)"的中间变量
u8 KeySPIBind[20] = {0}; //按键绑定
u8 KeyRefresh = 0; //有"设置"按键按下,便刷新所有推子模块按键
u32 KeySetData = 0; //推子模块"设置"按键(20个按键只能有一个有效)
u32 KeySetDataBK = 0; //存储原来"设置"按键值
u8 MainPage = 0; //"主页"按键标记(标记发送播放列表是否完成)
//总控模块界面按键设置
//低四位:
//bit0 : "主页"按键触发
//bit1 : "输入"按键触发
//bit2 : "输出"按键触发
//bit3 ;"信息"按键触发
//高四位:
//bit4 : "主页"界面显示
//bit5 : "输入"界面显示
//bit6 : "输出"界面显示
//bit7 : "信息"界面显示
u8 FaceKeySet = 0; //总控模块界面按键设置
u8 FaceKey = 0; //总控模块界面按键
u8 FaceKeyBK = 0;
u8 TalkKey = 0; //总控模块对讲按键
u8 TalkKeyBK = 0;
u8 EfctKey = 0; //总控模块效果按键
u8 EfctKeyBK = 0;
u8 ScenKey = 0; //总控模块场景按键
u8 ScenKeyBK = 0;
u8 ScenNum = 0; //场景编号
u8 SceneSetFlag = 0; //场景设置标记(为了使按下"场景"键时,只发送一次)
u8 SceneDelFlag = 0; //场景取消标记("场景"键有效时,再次按下"场景"键时,恢复临时场景)
u8 TempKeyState[20] = {0}; //临时按键状态
u8 ScenEffectState[20] = {0}; //场景设置中"设置"按键对应的效果
u8 EffectTest[13] = {0}; //效果测试
u8 EffectData[4][12] = {0}; //保存四个不同的效果设置
//保存效果设置编号(话筒输入板地址,效果编号,是否测试)(比如:0x3A,4,1)
//(EffectAddr:按推子模块顺序保存,即推子模块某路与哪一路输入模块绑定)
//(EffectAddr[i][0] 保存的是 : 按顺序与推子模块绑定的输入模块的地址)
u8 EffectAddr[20][3] = {0};
u8 TabTotal = 0; //节目列表总字节数(Tablen * 6 Byte)
u8 Tablen = 0; //节目列表总数
u8 TabNum = 0; //节目列表序号
u8 PlayTable[40][6] = {0}; //节目列表播出时间表(最多40条节目)
u8 Cmd71_SetFlg = 0; //0x71指令设置标记
u8 Cmd77_SetFlg = 0; //0x77指令设置标记(设置IP地址)
u8 Cmd79_SetFlg = 0; //0x79指令设置标记
u8 IPAddress[12] = {0}; //0x77指令(设置IP地址)
u8 InputState[20][12] = {0}; //20个推子,每个推子12个字节数据
u8 HotFireSet[4] = {0}; //热线定义数据
u8 HotFireClear = 0xFF; //"热线"按键屏蔽功能
u8 HotFireSPI[4] = {0}; //热线数据转换(转换成1-20)
u8 OutputSet[20] = {0}; //输出通道设置
u8 OutputGainSet[7] = {0}; //输出通道增益设置(还包含一个字节SyncMode)
u8 OutputGain[6] = {16,16,16,16,16,16}; //转换后的取值
u8 SyncMode = 0; //同步设置
u8 AddVoltage[5][4] = {0}; //话筒输入板加幻想电压(5个输入板,A/B/C/D四路)
u8 OutputGainDat[37] = {14,13,11,10,9,8,7,6,6,5,5,4,4,3,3,3,2,2,//输出增益对应的倍数 /* -1 ~ -18 */
16,18,20,23,25,28,32,36,40,45,51,57,64,71,80,90,101,113,127};/* 0 ~ 18 */
u8 ReadEEPData[320] = {0}; //从EEPROM读取数据
static void Delay(__IO uint32_t nCount)
{
for (; nCount != 0; nCount--);
}
int main(void)
{
u16 i = 0;
u8 h=0,L=0,cnt;
u8 KeySetBegin = 1; //用于初始化时,是否有"设置"按键刷新
u8 KeySetRenew = 0; //用于恢复临时场景时,是否有"设置"按键刷新
u8 EffectSetFlg = 0;//效果设置标记(为了使按下"效果"键时,只发送一次)
u8 TransMailBox = 0;//发送邮箱(在发送播放列表时使用)
System_Setup();
SPI_Configuration();
CAN_Configuration();
USART_Configuration();
I2C_EE_Init();
I2C_EE_BufferRead(ReadEEPData,EEP_IP_Address,12); //获取IP地址
printf("\n\nThe IP Data:\n");
for(i=0;i<12;i++)
{
IPAddress[i] = ReadEEPData[i];
printf("0x%X ",IPAddress[i]);
}
printf("\n\n");
LwIP_Init();
server_init();
////////////////////////////// *** 临时场景 *** ///////////////////////////////
//获取71指令标志位信息
I2C_EE_BufferRead(ReadEEPData,EEP_Cmd71_Address,1);
Cmd71_SetFlg = ReadEEPData[0];
//读取临时场景
if(Cmd71_SetFlg)
{
I2C_EE_BufferRead(ReadEEPData,EEP_TempScene_Address,271);
h = 0;
L = 0;
for(i=0;i<240;i++) //输入通道状态设置数据
{
InputState[L][h] = ReadEEPData[i];
h++;
if(h%12==0)
{
L++;
h=0;
}
}
for(h=0,i=240;i<244;i++)
HotFireSet[h++] = ReadEEPData[i];
for(h=0,i=244;i<264;i++)
OutputSet[h++] = ReadEEPData[i];
for(h=0,i=264;i<271;i++)
OutputGainSet[h++] = ReadEEPData[i];//(OutputGainSet[6]为一个字节SyncMode)
SyncMode = OutputGainSet[6];
if(HotFireSet[2]) //处理"热线"按键
{
for(i=0;i<20;i++)
if(HotFireSet[2] == InputState[i][8])break; //查找"热线"对应哪一路推子模块
HotFireClear = (((InputState[i][0]>>4)& 0x0F)-1)*4 + ((InputState[i][0]& 0x0F)-0x0A);
}
else
HotFireClear = 0xFF;
//加幻相电压
for(L=0;L<5;L++)
for(i=0;i<4;i++)
AddVoltage[L][i] = 0; //清零
for(i=0;i<20;i++)
{
if(InputState[i][7] == 0x03) //与推子模块绑定的是否是话筒输入板
{
L = ((InputState[i][8]>>4)& 0x0F)-0x01;
h = (InputState[i][8]& 0x0F)-0x0A;
if((L>=0x05)||(h>=0x04))continue;
if(InputState[i][10] == 0x01) //加幻相电压
{
AddVoltage[L][h] = 1;
}
else //不加幻相电压
AddVoltage[L][h] = 0;
}
}
}
I2C_EE_BufferRead(TempKeyState,EEP_TempKeyState_Address,20);//读取上一时刻按键状态
//读取效果设置信息(比如:0x3A,4,1)(话筒输入板地址,效果,是否测试)
//EffectAddr[L][h]在EEPROM中只保存(话筒输入板地址,效果)两条信息
I2C_EE_BufferRead(ReadEEPData,EEP_EffectAddr_Address,40);
h=0;
L=0;
for(i=0;i<40;i++)
{
EffectAddr[L][h] = ReadEEPData[i];
h++;
if(h%2 == 0)
{
L++;
h=0;
}
}
//读取4个效果信息
I2C_EE_BufferRead(ReadEEPData,EEP_EffectData_Address,48); //0x75协议(4个效果)
h = 0;
L = 0;
for(i=0;i<48;i++)
{
EffectData[L][h] = ReadEEPData[i];
h++;
if(h%12==0)
{
L++;
h=0;
}
}
//读取节目播放列表
I2C_EE_BufferRead(ReadEEPData,EEP_Tablen_Address,1); //0x78指令(节目列表)
TabTotal = ReadEEPData[0];
if(TabTotal>0)
{
Tablen = TabTotal/6; //总数
I2C_EE_BufferRead(ReadEEPData,EEP_PlayTable_Address,TabTotal);
h = 0;
L = 0;
for(i=0;i<TabTotal;i++)
{
PlayTable[L][h] = ReadEEPData[i];
h++;
if(h%6 == 0)
{
L++;
h=0;
}
}
}
I2C_EE_BufferRead(ReadEEPData,EEP_Cmd77_Address,1); //读取设置IP地址标记
Cmd77_SetFlg = ReadEEPData[0];
//若设置IP地址后,系统软复位,则需要读取外设(推子模块,输入模块,输出模块)地址
//因为此时外设并没有复位,也就没有发远程帧,通过读取设置IP地址系统复位前保存的
//地址,来确定外部设备存在的情况。
if(Cmd77_SetFlg)
{
//清零标志位(为了保证,只有在设置IP后系统软复位时,才读取。关机重启时不读取)
Cmd77_SetFlg = 0;
I2C_EE_ByteWrite(Cmd77_SetFlg,EEP_Cmd77_Address);
//推子模组地址
I2C_EE_BufferRead(ReadEEPData,EEP_Tuizi_Address,10);
for(i=0,h=0;i<10;i++)
{
if(ReadEEPData[i])
{
TuiziAddr[h] = ((ReadEEPData[i]<<8)|(ReadEEPData[i+1]))& 0x7FF;
// printf("(0).TuiziAddr[%d] = 0x%X\n",h,TuiziAddr[h]);
i++;
h++;
}
else
{
i++;
h++;
}
}
//=== 初始化前一时刻推子模块状态 ===//
if(TuiziAddr[0] != 0)
{
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.StdId = TuiziAddr[0]; //0x100
for(i=0;i<4;i++)
{
TxMessage.Data[0] = (InputState[i][7]<<4)|(i+1); //高4位信号格式,低4位数据包编号
TxMessage.Data[1] = InputState[i][8]; //输入模块地址
for(h=2;h<8;h++)
TxMessage.Data[h] = InputState[i][h-1]; //6字节汉字码
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;
TxMessage.StdId = 0x101;
for(i=0;i<4;i++)
{
TxMessage.Data[i] = TempKeyState[i];
KeyDataBK[i] = TempKeyState[i];
if(((TempKeyState[i]>>3)& 0x01) == 0x01) //"设置"键是否有效
KeySetBegin = 1;
}
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
if(TuiziAddr[1] != 0)
{
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.StdId = TuiziAddr[1];
for(i=4;i<8;i++)
{
TxMessage.Data[0] = (InputState[i][7]<<4)|(i-3); //高4位信号格式,低4位数据包编号
TxMessage.Data[1] = InputState[i][8]; //输入模块地址
for(h=2;h<8;h++)
TxMessage.Data[h] = InputState[i][h-1]; //6字节汉字码
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;
TxMessage.StdId = 0x201;
for(h=0,i=4;i<8;i++)
{
TxMessage.Data[h++] = TempKeyState[i];
KeyDataBK[i] = TempKeyState[i];
if(((TempKeyState[i]>>3)& 0x01) == 0x01) //"设置"键是否有效
KeySetBegin = 1;
}
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
if(TuiziAddr[2] != 0)
{
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.StdId = TuiziAddr[2];
for(i=8;i<12;i++)
{
TxMessage.Data[0] = (InputState[i][7]<<4)|(i-7); //高4位信号格式,低4位数据包编号
TxMessage.Data[1] = InputState[i][8];
for(h=2;h<8;h++)
TxMessage.Data[h] = InputState[i][h-1]; //6字节汉字码
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;
TxMessage.StdId = 0x301;
for(h=0,i=8;i<12;i++)
{
TxMessage.Data[h++] = TempKeyState[i];
KeyDataBK[i] = TempKeyState[i];
if(((TempKeyState[i]>>3)& 0x01) == 0x01) //"设置"键是否有效
KeySetBegin = 1;
}
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
if(TuiziAddr[3] != 0)
{
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.StdId = TuiziAddr[3];
for(i=12;i<16;i++)
{
TxMessage.Data[0] = (InputState[i][7]<<4)|(i-11);//高4位信号格式,低4位数据包编号
TxMessage.Data[1] = InputState[i][8];
for(h=2;h<8;h++)
TxMessage.Data[h] = InputState[i][h-1]; //6字节汉字码
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;
TxMessage.StdId = 0x401;
for(h=0,i=12;i<16;i++)
{
TxMessage.Data[h++] = TempKeyState[i];
KeyDataBK[i] = TempKeyState[i];
if(((TempKeyState[i]>>3)& 0x01) == 0x01) //"设置"键是否有效
KeySetBegin = 1;
}
while(((CAN1->TSR>>26)& 0x07) == 0);
CAN_Transmit(CAN1, &TxMessage);
}
if(TuiziAddr[4] != 0)
{
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.StdId = TuiziAddr[4];
for(i=16;i<20;i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -