本帖最后由 Swallow_0322 于 2011-6-14 17:38 编辑
源文件:
I2C.CPP
- #include "main.h"
- __OPT_INLINE__ I2C1_t::I2C1_t():sem(0) //构造函数
- {
- //I2C的引脚配置及时钟配置使用LOOK配置
- SubAddr = 0xA0; //I2C设备地址
- for (uint32_t i = 0; i < sizeof(TxBuffer); i ++)
- { //清空缓存
- TxBuffer = 0;
- RxBuffer = 0;
- }
- SYSCLKs.APBCLK.Bits.I2C1_EN = 1;
- SYSs.IPRSTC2.Bits.I2C1_RST = 1; //I2C1模块复位
- SYSs.IPRSTC2.Bits.I2C1_RST = 0; //I2C1正常工作
- I2C1s.CON.Bits.ENSI = 1; //允许I2C串行功能
- I2C1s.CLK.Regs = ((12000000/2*10)/(50000 * 4) + 5) / 10 - 1;
- I2C1s.CON.Bits.EI = 1; //I2C1 使能中断
- I2C1s.CON.Bits.STA = 0; //I2C1起始标志清零
- I2C1s.CON.Bits.STO = 0; //I2C1结束标志清零
- I2C1s.CON.Bits.AA = 0; //I2C1应答标志清零
- I2C1s.CON.Bits.EI = 1; //I2C1 使能中断
- I2C1s.CON.Bits.ENSI = 1; //允许I2C串行功能
- I2C1s.CON.Bits.SI= 1; //清中断标志位
- attach(I2C1_IRQn);
- vector_t::enable(I2C1_IRQn);
- }
- // 中断服务例程
- bool I2C1_t::isr(int vector)
- {
- bool Back_Val = FALSE;
- switch(I2C1s.STATUS.Regs& 0xf8)
- {
- case I2C_START: //主机收到自己发送的开始信号
- if (State == I2C_START) { //本次中断应该接收TW_START信号
- I2C1s.DATA.Regs = SubAddr & 0xfe; //发送子机地址(写)
- I2C1s.CON.Bits.STA = 0;
- I2C1s.CON.Bits.SI = 1; //STA位必须清除,否则死机 清除中断标志
- State = I2C_MT_SLA_ACK; //Status下次I2C_MT_SLA_ACK
- }
- else
- {
- Exit(); //通讯失败
- Back_Val = TRUE;
- }
- break;
- case I2C_REP_START: //主机收到自己发送的重新开始信号
- if (State == I2C_REP_START) { //本次中断应该接收TW_RESTART信号
- I2C1s.DATA.Regs = SubAddr | 0x01; //发送子机地址(读)
- I2C1s.CON.Bits.STA = 0; //STA位必须清除,否则死机 清除中断标志
- I2C1s.CON.Bits.SI = 1;
- I2C1s.CON.Bits.AA = 1;
- State = I2C_MR_SLA_ACK; //Status下次I2C_MR_SLA_ACK
- }
- else
- {
- Exit(); //通讯失败
- Back_Val = TRUE;
- }
- break;
- case I2C_MT_SLA_ACK: //主发机接收到从机的地址应答信号后发送命令
- if (State == I2C_MT_SLA_ACK) { //本次中断应该接收TW_MT_SLA_ACK信号
- State = I2C_MT_DATA_ACK; //Status下次应该收TW_MT_DATA_ACK
- I2C1s.DATA.Regs = SubComm; //发送子机命令
- I2C1s.CON.Bits.SI = 1;
- I2C1s.CON.Bits.AA = 1;
- }
- else
- {
- Exit(); //通讯失败
- Back_Val = TRUE;
- }
- break;
- case I2C_MR_SLA_ACK: //主收机接收到从机的地址应答信号
- if ((State == I2C_MR_SLA_ACK) && SubCount) { //本次中断应该接收TW_MR_SLA_ACK信号
- State = I2C_MR_DATA_ACK; //Status下次应该收TW_MR_DATA_ACK
- I2C1s.CON.Bits.SI = 1;
- I2C1s.CON.Bits.AA = 1;
- }
- else
- {
- Exit(); //通讯失败
- Back_Val = TRUE;
- }
- break;
- case I2C_MT_DATA_ACK: //主收机接收到从机的数据应答信号
- if ((State == I2C_MT_DATA_ACK) && (Count < MainCount)) {//本次中断应该接收TW_MT_DATA_ACK信号
- I2C1s.DATA.Regs = TxBuffer[Count ++];//发送子机数据
- I2C1s.CON.Bits.SI = 1;
- I2C1s.CON.Bits.AA = 1;
- }
- else {
- if ((State == I2C_MT_DATA_ACK) && (Count == MainCount) && (SubAddr & 1)) {//本次中断应该接收TW_MT_DATA_ACK信号
- REStart();//
- }
- else
- {
- Stop(); //通讯成功
- Back_Val = TRUE;
- }
- }
- break;
- case I2C_MR_DATA_ACK:
- if ((State == I2C_MR_DATA_ACK) && (Count < SubCount)) {
- RxBuffer[Count ++] = I2C1s.DATA.Regs;//接收子机数据
- if (Count < SubCount) {
- I2C1s.CON.Bits.SI = 1;
- I2C1s.CON.Bits.AA = 1;
- }
- else {
- I2C1s.CON.Bits.AA = 0;
- I2C1s.CON.Bits.SI = 1;
- State = I2C_MR_DATA_NACK;//下次进入I2C_MR_DATA_NACK,接收数据准备完成
- }
- }
- else
- {
- Exit(); //通讯失败
- Back_Val = TRUE;
- }
- break;
- case I2C_MR_DATA_NACK: //数据接收结束
- if ((State == I2C_MR_DATA_NACK) && (Count == SubCount)) {
- Stop(); //通讯成功
- }
- else Exit(); //通讯失败
- Back_Val = TRUE;
- break;
- // case I2C_MT_DATA_NACK:
- // Exit();//通讯失败
- // break;
- default:
- Exit(); //通讯失败
- Back_Val = TRUE;
- break;
- }
- return Back_Val;
- }
- // 中断滞后服务例程
- void I2C1_t::dsr(int vector, uintptr_t count)
- {
- sem.do_post(); //释放一个信号量资源
- }
- void I2C1_t::Start(void)
- {
- Busy = true;
- State = I2C_START; //主机准备发送启始位
- Count = 0; //发送数据个数
- //SystickCount = 0; //清除节拍计数器
- I2C1s.CON.Bits.STO = 0; //I2C1结束标志清零
- I2C1s.CON.Bits.AA = 0; //I2C1应答标志清零
- I2C1s.CON.Bits.EI = 1; //I2C1 使能中断
- I2C1s.CON.Bits.ENSI = 1; //允许I2C串行功能
- I2C1s.CON.Bits.SI= 1; //清中断标志位
- I2C1s.CON.Bits.STA = 1; //I2C1起始标志置位
- //delay(LOOK_TICKS_PER_SEC);
- while(!sem.wait());
- // task = &scheduler.get_current_task();
- // delay(); // 阻塞任务
- }
- void I2C1_t::REStart(void)
- {
- Busy = true;
- State = I2C_REP_START; //主机准备发送启始位
- Count = 0; //发送数据个数
- I2C1s.CON.Bits.STA = 1; //I2C1起始标志置位
- I2C1s.CON.Bits.SI= 1; //清中断标志位*/
- }
- void I2C1_t::Stop(void)
- {
- Busy = false;
- State = I2C_BUS_OK;//通讯成功
- I2C1s.CON.Bits.STO = 1; //I2C1结束标志置位
- I2C1s.CON.Bits.SI = 1; //清中断标志位*/
- }
- void I2C1_t::Exit(void)
- {
- Busy = false;
- State = I2C_BUS_ERROR; //通讯失败
- I2C1s.CON.Bits.STO = 1; //I2C1结束标志置位
- I2C1s.CON.Bits.SI = 1; //清中断标志位
- }
- unsigned char I2C1_t::ReadByte(unsigned int Address, unsigned char *Data)
- {
- SubAddr |= 0x01;
- MainCount = 0; //发送0个数据(只读)
- //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
- SubComm = Address; //读出地址
- SubCount = 1; //接收1个数据
- //SystickCount = 0;
- Start(); //启动I2C模块
- if (State == I2C_BUS_OK)
- {
- //通讯成功
- Data[0] = RxBuffer[0]; //从接收缓冲区取出一个字节
- }
- return State; //(读出数据在RxBuffer[0]~RxBuffer[15])
- }
- unsigned char I2C1_t::WriteByte(unsigned int Address, unsigned char Data)
- {
- SubAddr &= 0xfe;
- MainCount = 1; //发送1个数据
- //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
- SubComm = Address; //写入地址
- TxBuffer[0] = Data; //写入1个数据到发送缓冲区
- SubCount = 0; //接收0个数据
- Start(); //启动I2C模块
- delay(LOOK_TICKS_PER_SEC/10); //延时100mS等待写入完成
- return State;
- }
- unsigned char I2C1_t::ReadBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
- {
- SubAddr |= 0x01;
- MainCount = 0;//发送0个数据(只读)
- //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
- SubComm = Address;//读出地址
- SubCount = (Cnt <= sizeof(RxBuffer)) ? Cnt : sizeof(RxBuffer);//接收Cnt个数据
- Start();//启动I2C模块
- if (State == I2C_BUS_OK) {//通讯成功
- for (uint8_t i = 0; i < SubCount; i ++) Data = RxBuffer;//从接收缓冲区取出Cnt个字节
- }
- return State;//(读出数据在RxBuffer[0]~RxBuffer[15])
- }
- unsigned char I2C1_t::WriteBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
- {
- SubAddr &= 0xfe;
- MainCount = (Cnt <= sizeof(TxBuffer)) ? Cnt : sizeof(TxBuffer);//发送Cnt个数据
- //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
- SubComm = Address;//写入地址
- for (uint8_t i = 0; i < MainCount; i ++) TxBuffer = Data;//写入Cnt个数据到发送缓冲区
- SubCount = 0;//接收0个数据
- Start();//启动I2C模块
- delay(LOOK_TICKS_PER_SEC/10); //延时100mS等待写入完成
- return State;
- }
- unsigned int I2C1_t::GetState(void)
- {
- return State;
- }
- void I2C1_t::SetAddress(unsigned int I2CAddress)
- {
- SubAddr = I2CAddress;
- }
- /*void I2cObj::SetSystickCount(void)
- {
- SystickCount ++;
- }*/
- I2C1_t I2C_1;
led.cpp
-
- #include "main.h"
- flag_t Flag(0); //位0为LED闪烁模式 位1为KEY1控制蜂鸣器任务同步标志 位2为UART通信控制蜂鸣器任务同步标志
- flag_t Flag_I2C(0); //通过I2C读写AT24c16同步标志
- // uart0 构造函数
- __OPT_INLINE__ uart0_t::uart0_t()
- {
- attach(UART0_IRQn);
- vector_t::enable(UART0_IRQn);
- SYSs.IPRSTC2.Bits.UART0_RST = 1; //UART0 模块复位
- SYSs.IPRSTC2.Bits.UART0_RST = 0; //UART0 模块正常工作
- UART0s.FCR.Bits.TFR = 1; //TX 软件复位
- UART0s.FCR.Bits.RFR = 1; //RX 软件复位
- UART0s.FCR.Bits.RFITL = 0x00; //Rx FIFO中断 (INT_RDA) 触发级别 1位
-
- UART0s.LCR.Bits.SPE = 0; //无校验 奇偶使能位
- UART0s.LCR.Bits.EPE = 0; // 0----奇校验 1----偶校验
- UART0s.LCR.Bits.PBE = 0;
- UART0s.LCR.Bits.WLS = 0b011; //字长度选择 8bits
- UART0s.LCR.Bits.NSB = 0; //1位停止位
-
- UART0s.BAUD.Bits.BRD = 0x66; //外部12MHz 115200bps 对波特率分频寄存器的设置波特率分频设置即该句必须放在第一位
- UART0s.BAUD.Bits.DIV_X_EN = 1; //使能分频X
- UART0s.BAUD.Bits.DIV_X_ONE = 1; //Divider X equal 1
- UART0s.IER.Bits.RDA_IEN = 1; //使能接收中断
- /*
- DIV_X_EN DIV_X_ONE Divider X BRD 波特率公式
- Disable 0 B A UART_CLK / [16 * (A+2)]
- Enable 0 B A UART_CLK / [(B+1) * (A+2)] , B must >= 8
- Enable 1 B A UART_CLK / (A+2), A must >=3
- */
- }
- // uart0 输出
- void uart0_t::puts(const char* str)
- {
- fillfifo(str); // 填充 fifo
- UART0s.IER.Bits.THRE_IEN = 1; // 允许发送中断
- task = &scheduler.get_current_task();
- delay(); // 阻塞任务
- }
- void uart0_t::put_numeral(uint8_t data)
- {
- char str[2];
- char *p;
- str[0] = ((data/16%16>9)?(data/16%16+'A'-10)data/16%16+'0'));
- str[1] = ((data%16>9)?(data%16+'A'-10)data%16+'0'));
- p = &str[0];
- puts(p);
- }
- // uart0 中断服务例程
- bool uart0_t::isr(int vector)
- {
- if (UART0s.ISR.Bits.THRE_INT==1)
- {
- //UART0发送中断
- const char* str = buffer;
- if (str == 0) { // 无数据
- UART0s.IER.Bits.THRE_IEN = 0; // 禁止发送中断
- return true;
- }
- fillfifo(str); // 填充 fifo
- return false;
- }
- if (UART0s.ISR.Bits.RDA_INT==1)
- {
- //UART0接收中断
- /* Get all the input characters */
- while(UART0s.ISR.Bits.RDA_IF)
- {
- /* Get the character from UART Buffer */
- char Received_Data = UART0s.DATA.Regs;
- switch (Received_Data)
- {
- case '1':
- //执行蜂鸣器响3次的任务
- Flag.do_set_bits(0b0100);
- break;
- case '3':
- task_ad.sem.do_post(); //释放一个信号量资源
- break;
- case 'R':
- Flag_I2C.do_set_bits(0b01);
- break;
- case 'r':
- Flag_I2C.do_set_bits(0b010);
- break;
- case 'U':
- Flag_I2C.do_set_bits(0b0100);
- break;
- case 'u':
- Flag_I2C.do_set_bits(0b01000);
- break;
- case 'D':
- Flag_I2C.do_set_bits(0b010000);
- break;
- case 'd':
- Flag_I2C.do_set_bits(0b0100000);
- break;
- case '2':
- //执行与KEY2相同的动作
- int ** = Flag.peek();
- if (**&0b01)
- Flag.do_mask_bits(~0b01); //清除事件标志 位0
- else
- Flag.do_set_bits(0b01); //置位事件标志 位0
- break;
- }
- return false;
- }
- }
- return false;
- }
- // uart0 中断滞后服务例程
- // 所有数据发送完成后,dsr() 被调用
- void uart0_t::dsr(int vector, uintptr_t count)
- {
- task->do_wakeup(); // 唤醒任务
- }
- // uart0 填充 fifo
- void uart0_t::fillfifo(const char* str)
- {
- do {
- char ch;
- ch = *str++;
- if (ch == 0) {
- str = 0;
- break;
- }
- UART0s.DATA.Regs = ch;
- } while (!UART0s.FSR.Bits.TX_FULL);
- buffer = str;
- }
- uart0_t uart0; // 创建 uart0 对象
- // 任务类 task_led_t 的例程
- void task_led_t::routine()
- {
- // TODO: 在此编写 task_led_t 例程的内容
- GPIOAs.DMASK.Regs = ~0b111100;
- GPIOAs.DOUT.Regs = ~0b100;
- while (true)
- {
- // TODO: 在此编写 task_led_t 例程的内容
- uint32_t data = GPIOAs.DOUT.Regs & 0b111100;
- int flag = Flag.peek();
- if (flag)
- {
- data <<= 1;
- data += data >> 4;
- }
- else
- {
- data >>= 1;
- data += data << 4;
- }
- GPIOAs.DOUT.Regs = data;
- delay(LOOK_TICKS_PER_SEC/2);
- }
- }
- // 任务类 task_key_t 的例程
- void task_key_t::routine()
- {
- // TODO: 在此编写 task_key_t 例程的内容
- while (true)
- {
- // TODO: 在此编写 task_key_t 例程的内容
- uint32_t Key_Val = key_read();
- if ((Key_Val&(1<<14))==0)
- {
- //KEY2 按下
- int ** = Flag.peek();
- if (**&0b01)
- Flag.mask_bits(~0b01); //清除事件标志 位0
- else
- Flag.set_bits(0b01); //置位事件标志 位0
- }
- if ((Key_Val&(1<<15))==0)
- {
- //KEY1 按下
- Flag.do_set_bits(0b010);
- }
- delay(LOOK_TICKS_PER_SEC/10);
- }
- }
- // 任务类 task_key_t 的成员函数
- __OPT_INLINE__ int32_t task_key_t::key_read()
- {
- uint32_t Key_Tmp = TRUE;
- static uint32_t Key_Record = KEY_NO_DOWN; //按键记录
- Key_Tmp = GPIOBs.PIN.Regs&KEY_NO_DOWN;
- if(Key_Tmp==KEY_NO_DOWN) //无有效按键按下
- {
- Key_Record = KEY_NO_DOWN; //清除按键记录
- return KEY_NO_DOWN; //程序退出
- }
- if(Key_Record!=Key_Tmp) //为新按键
- {
- Key_Record = Key_Tmp; //保存本次结果
- delay(LOOK_TICKS_PER_SEC/100); //延时去抖动
- Key_Tmp = GPIOBs.PIN.Regs&KEY_NO_DOWN;
- if(Key_Tmp==Key_Record)
- return Key_Tmp;
- }
- return KEY_NO_DOWN;
- }
- // 任务类 task_beep_t 的例程
- void task_beep_t::routine()
- {
- // TODO: 在此编写 task_beep_t 例程的内容
- GPIOBs.DOUT.Bits.Pin10 = 0; //蜂鸣器不响
- while (true)
- {
- // TODO: 在此编写 task_beep_t 例程的内容
- int flag = Flag.wait(0b110, flag_t::ANY_CONSUME);
- if (flag)
- {
- uart0.puts("Buzzer rang three times!\n");
- for (uint32_t i = 0; i < 6; i ++)
- {
- //蜂鸣器响三次
- GPIOBs.DOUT.Bits.Pin10 ^= 1; //蜂鸣器响PB10=1,不响PB10=0
- delay(LOOK_TICKS_PER_SEC); //断续间隔
- }
- }
- }
- }
- // 任务类 task_ad_t 的例程
- void task_ad_t::routine()
- {
- // TODO: 在此编写 task_ad_t 例程的内容
- SYSs.IPRSTC2.Bits.ADC_RST = 1;
- SYSs.IPRSTC2.Bits.ADC_RST = 0; /* Reset ADC */
- //ADC时钟、分频及配置为AD引脚在look中配置
- ADCs.ADCR.Bits.ADEN = 1; //使能AD模块
- ADCs.ADCALR.Bits.CALEN = 1; //自校正使能
- while(!ADCs.ADCALR.Bits.CALDONE); //等待自校正结束
- ADCs.ADCR.Bits.DIFFEN = 0; //单端输入
- ADCs.ADCR.Bits.ADST = 0; //停止AD
- ADCs.ADCR.Bits.ADMD = 0; //单一转换
- ADCs.ADCHER.Bits.CHEN = 0x02; //模拟输入通道1使能
- ADCs.ADSR.Bits.ADF = 1; //清AD中断标志
- while (true)
- {
- // TODO: 在此编写 task_ad_t 例程的内容
- if (sem.wait())
- {
- ADCs.ADCR.Bits.ADST = 1; //启动AD
- while(!ADCs.ADSR.Bits.ADF); //等待转换结束
- ADCs.ADSR.Bits.ADF = 1; //清AD中断标志
- uint32_t AD_Result = ADCs.ADDR1.Regs&0xFFF;
- char str[4];
- char *p;
- str[0] = AD_Result/1000+'0';
- str[1] = AD_Result/100%10+'0';
- str[2] = AD_Result/10%10+'0';
- str[3] = AD_Result%10+'0';
- p = &str[0];
- uart0.puts("ADC_RESULT_AD1:");
- uart0.puts(p);
- }
-
- }
- }
- // 任务类 task_AT24C16_t 的例程
- void task_AT24C16_t::routine()
- {
- // TODO: 在此编写 task_beep_t 例程的内容
- uint8_t EEPROM_Data = 0; //IIC地址0x00读写数据
- uint8_t I2C_Page_Test[16]; //IIC地址0x10页读写数据
- uint8_t i = 0;
- while (true)
- {
- // TODO: 在此编写 task_beep_t 例程的内容
- //uint8_t ** = Flag_I2C.peek();
- int flag = Flag_I2C.wait(0b0111111, flag_t::ANY_CONSUME);
- switch (flag)
- {
- case 0x01:
- if (I2C_BUS_OK==I2C_1.ReadBuffer(0x10,I2C_Page_Test,16))
- {
- uart0.puts("\nAT24C16地址0x10开始16字节的内容为:\n");
- for (i=0;i<16;i++)
- uart0.put_numeral(I2C_Page_Test);
- }
- else
- uart0.puts("\nAT24C16地址0x10开始16字节的内容读取失败!");
- break;
- case 0x02:
- if (I2C_BUS_OK==I2C_1.ReadByte(0x00,&EEPROM_Data))
- {
- uart0.puts("\nAT24C16地址0的内容为:0x");
- uart0.put_numeral(EEPROM_Data);
- }
- else
- uart0.puts("\nAT24C16地址0的内容读取失败!");
- break;
- case 0x04:
- for (i=0;i<16;i++)
- I2C_Page_Test++;
- if (I2C_BUS_OK==I2C_1.WriteBuffer(0x10,I2C_Page_Test,16))
- uart0.puts("\nAT24C16地址0x10开始16字节的内容加1成功!");
- else
- {
- uart0.puts("\nAT24C16地址0x10开始16字节的内容加1失败!");
- for (i=0;i<16;i++)
- I2C_Page_Test--;
- }
- break;
- case 0x08:
- if (I2C_BUS_OK==I2C_1.WriteByte(0x00,++EEPROM_Data))
- uart0.puts("\nAT24C16地址0的内容加1成功!");
- else
- uart0.puts("\nAT24C16地址0的内容加1失败!");
- break;
- case 0x10:
- for (i=0;i<16;i++)
- I2C_Page_Test--;
- if (I2C_BUS_OK==I2C_1.WriteBuffer(0x10,I2C_Page_Test,16))
- uart0.puts("\nAT24C16地址0x10开始16字节的内容减1成功!");
- else
- {
- uart0.puts("\nAT24C16地址0x10开始16字节的内容减1失败!");
- for (i=0;i<16;i++)
- I2C_Page_Test++;
- }
- break;
- case 0x20:
- if (I2C_BUS_OK==I2C_1.WriteByte(0x00,--EEPROM_Data))
- uart0.puts("\nAT24C16地址0的内容减1成功!");
- else
- uart0.puts("\nAT24C16地址0的内容减1失败!");
- break;
- default:
- uart0.puts("\nAT24C16读写操作错误!");
- }
- }
- }
- #ifdef LOOK_SCHEDULING_PRIORITY
- instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key(0);
- instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep(3);
- instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led(2);
- instantiate::task<task_ad_t, LOOK_STACK_SIZE> task_ad(1);
- instantiate::task<task_AT24C16_t, LOOK_STACK_SIZE> task_AT24C16(4);
- #else
- instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key;
- instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep;
- instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
- instantiate::task<task_ad_t, LOOK_STACK_SIZE> task_ad;
- instantiate::task<task_AT24C16_t, LOOK_STACK_SIZE> task_AT24C16;
- #endif
|