📄 main.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: main.c
** Last modified Date: 2004-09-16
** Last Version: 1.0
** Descriptions: The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by: Chenmingji
** Created date: 2004-09-16
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by: lgl
** Modified date: 2007-08-11
** Version:
** Descriptions: 允许跨页读写操作,配套USB_RW_FM24CL04上位机软件
** ZLG/USB23xx软件包使用了5个信号量(1个用于控制传输任务;4个用于端点的数据收发)
** I2C软件包用了2个信号量
** 主函数用了2个信号量,故OS_CFG.h中最大事件数至少为9
********************************************************************************************************/
#include "main.h" // 包含本应用程序的相关头文件
#include "I2C.h" //
#include "USBConfig.h" // 软件包的配置头文件
#include "USBDriver.h" // 软件包 API 函数头文件
OS_STK TaskStartStk[128]; // 操作系统起动任务堆栈
OS_STK ReadTaskStk [256]; // 读任务堆栈
OS_STK WriteTaskStk[256]; // 写任务堆栈
OS_EVENT *Write_Sem; // 读任务就绪信号量
OS_EVENT *Read_Sem; // 写任务就绪信号量
#define FM24CL04 0xA0 // 宏定义铁电存储器的器件地址
#define FM24CL04_FirstPage (0xA0|(0<<1)) // FM24CL04的第1页
#define FM24CL04_SecondPage (0xA0|(1<<1)) // FM24CL04的第2页
#define I2C0_VIC 9 // 宏定义I2C0的VIC通道号
#define Usb_VIC 22 // 宏定义UDC的VIC通道号
#define CMD_READ_24C02 0x01 // 读FM24CL04命令
#define CMD_WRITE_24C02 0x02 // 写FM24CL04命令
typedef struct tagCmd // 读写FM24CL04命令结构体
{
INT8U cmd; // 命令: 1 -- 读; 2 -- 写
INT8U addr; // I2C器件FM24CL04的地址
INT16U offset; // 读写FM24CL04存储空间的偏移地址
INT16U len; // 读写长度
}I2C_COMMAND;
I2C_COMMAND I2C_2; // 读写命令结构变量
void TaskStart(void *pdata); // 起动任务函数原型声明
void TaskRead (void *pdata); // 读任务函数原型声明
void TaskWrite(void *pdata); // 写任务函数原型声明
INT16U Read_FM24CL04(INT8U addr,INT16U offset,INT16U len,INT8U *recbuff);
INT16U Write_FM24CL04(INT8U addr,INT16U offset,INT16U len,INT8U *writebuff);
/*******************************************************************************************************
主 函 数
*******************************************************************************************************/
int main (void)
{
OSInit(); // 初始化uC/OS-II
OSTaskCreate(TaskStart,(void *)0,&TaskStartStk[127],3); // 创建起动任务
OSStart(); // 开始多任务
}
/*******************************************************************************************************
* 起动任务, 优先级 3
********************************************************************************************************/
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3 // CPU状态寄存器的分配存储
OS_CPU_SR cpu_sr;
#endif
INT8U err;
pdata = pdata; // 防止编译器报警
TargetInit(); // μC/OS-II定时器及相关中断初始化
I2cInit(100000); // I2C初始化
SetVICIRQ(Usb_VIC,1,(uint32)Usb_Exception); // 设置USB中断,中断优先级为1
SetVICIRQ(I2C0_VIC,2,(uint32)I2c_Exception);// 设置I2C0中断,中断优先级为2
err = USB_Initialize(); // USB 初始化
Write_Sem = OSSemCreate(0); // 创建控制读写任务的两个信号量,信号量初值为0
Read_Sem = OSSemCreate(0);
OSTaskCreate(TaskRead,(void *)0, &ReadTaskStk[255], 1); //创建读任务
OSTaskCreate(TaskWrite,(void *)0, &WriteTaskStk[255], 2); //创建写任务
if (err == 0) // 初始化USB成功,才创建传输控制处理任务
OSTaskCreate(TaskSetup, (void *)0, &TaskSetupStk[127], 0);
while(1)
{
err = ReadPort1(sizeof(I2C_COMMAND),(INT8U *)&I2C_2,200); //等待来自PC机的命令
if (err == OS_NO_ERR) // 接收正确
{
if (I2C_2.cmd == CMD_READ_24C02)
OSSemPost(Read_Sem); //使读任务就绪(计数信号量的值加1)
if (I2C_2.cmd == CMD_WRITE_24C02)
OSSemPost(Write_Sem); //使写任务就绪
}
}
}
/********************************************************************************************
** 函数名称: void TaskRead(void *pdata)
** 功能描述: 写 CAT24WC02 任务,优先级为1
** 输 入: 无
** 输 出: 无
********************************************************************************************/
void TaskRead(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 // CPU状态寄存器的分配存储
OS_CPU_SR cpu_sr;
#endif
INT8U err;
INT8U buff[514]; // 接收缓冲区
INT8U ack = 0x01; // 应答字
INT16U read_len=0;
for (;;)
{
OSSemPend(Read_Sem,0,&err); // 等待TaskStart读命令(等待后,信号量值减1)
err = WritePort1(1,&ack,200); // 应答PC主机
if (err == USB_NO_ERR) // 应答正确
{
/* 按照设置参数从铁电存储器的offset地址处开始读取len字节数据 */
read_len=Read_FM24CL04(FM24CL04,I2C_2.offset,I2C_2.len,&buff[2]);
buff[0] = read_len / 256; // 读取到的字节数高字节
buff[1] = read_len % 256; // 读取到的字节数低字节
WritePort2(read_len + 2,buff,200); // 发送读取到的数据及数据长度值
}
}
}
/********************************************************************************************
** 函数名称: void TaskWrite(void *pdata)
** 功能描述: 写 CAT24WC02 任务,优先级为2
** 输 入: 无
** 输 出: 无
********************************************************************************************/
void TaskWrite(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 // CPU状态寄存器的分配存储
OS_CPU_SR cpu_sr;
#endif
INT8U err,buff[514]; //发送缓冲区
INT8U ack = 0x02; //应答字
INT16U write_len=0;
for (;;)
{
OSSemPend(Write_Sem,0,&err); // 等待TaskStart的命令
err = WritePort1(1,&ack,200); // 应答PC机
if (err == USB_NO_ERR) // 应答正确
{
err = ReadPort2(I2C_2.len,&buff[2],500); // 接收要写入的数据
if (err == USB_NO_ERR)//接收正确
{
/* 按照设置参数从铁电存储器的offset地址处开始写入len字节数据 */
write_len=Write_FM24CL04(FM24CL04,I2C_2.offset,I2C_2.len,&buff[2]);
buff[0] = write_len / 256; // 计算写入的有效数据的字节数
buff[1] = write_len % 256;
WritePort1(2,&buff[0],200); // 发送实际写入的字节数
}
}
}
}
/**************************************************************************************
** 函数名称: INT16U Read_FM24CL04(INT8U addr,INT16U offset,INT16U len,INT8U *recbuff)
** 功能描述: 从FM24CL04的offset地址处读取len字节数据,放入recbuff缓冲区中
** 输 入: INT8U addr 器件地址0xA0
** INT16U offset 读操作起始地址
** INT16U len 读字节数
** INT8U *recbuff 接收数据的指针
** 输 出: 读取成功返回实际读取到的字节数;否则返回0
***************************************************************************************/
INT16U Read_FM24CL04(INT8U addr,INT16U offset,INT16U len,INT8U *recbuff)
{
INT8U page_addr=offset&0xff; // 页内操作起始地址
INT16U read_len;
if(offset<256) // 若起始地址在第1页范围内
{
if((offset+len)>256) // 若为跨页操作
{
// 先从第1页读部分数据
read_len=I2cRead(FM24CL04_FirstPage,recbuff,&page_addr,1,(256-offset));
page_addr=0;
// 再从第2页读剩余部分数据
read_len+=I2cRead(FM24CL04_SecondPage,&recbuff[read_len],&page_addr,1,(len-read_len));
}
else // 操作仅在第1页内进行
read_len=I2cRead(FM24CL04_FirstPage,recbuff,&page_addr,1,len); //先从第1页读数据
}
else // 操作仅在第2页内进行
read_len=I2cRead(FM24CL04_SecondPage,recbuff,&page_addr,1,len);
if(read_len==len)
return read_len; // 读取成功,返回实际读到的字节数
else
return 0; // 读取失败,返回0
}
/****************************************************************************************
** 函数名称: INT16U Write_FM24CL04(INT8U addr,INT16U offset,INT16U len,INT8U *writebuff)
** 功能描述: 从FM24CL04的offset地址处写入len字节数据
** 输 入: INT8U addr 器件地址0xA0
** INT16U offset 读操作起始地址
** INT16U len 读字节数
** INT8U *writebuff 指向写入数据缓冲区的指针
** 输 出: 写入成功返回写入的有效字节数;否则返回0
*****************************************************************************************/
INT16U Write_FM24CL04(INT8U addr,INT16U offset,INT16U len,INT8U *writebuff)
{
INT8U w_buff1[257],w_buff2[257];
INT16U write_len; // 写入字节数
w_buff1[0]=offset & 0xff; // 取页内偏移地址
if(offset<256) // 若起始地址在第1页范围内
{
if((offset+len)>256) // 若为跨页写操作
{
memcpy(&w_buff1[1],&writebuff[0],(256-offset)); // 将待写入数据分成两部分
memcpy(&w_buff2[1],&writebuff[256-offset],(len-(256-offset))); // 第2页部分数据
write_len=I2cWrite(FM24CL04_FirstPage,w_buff1,(256-offset+1)); // 写入数据
w_buff2[0]=0x00;
write_len+=I2cWrite(FM24CL04_SecondPage,w_buff2,(len-(256-offset)+1)); // 写入数据
if(write_len!=len+2)
return 0;
else
return (write_len-2); // 返回写入的有效数据字节数
}
else // 操作仅在第1页内进行
{
memcpy(&w_buff1[1],&writebuff[0],len); // 将待写入数据分成两部分
write_len=I2cWrite(FM24CL04_FirstPage,w_buff1,(len+1)); // 写入数据
}
}
else // 若在第2页内操作
{
memcpy(&w_buff1[1],&writebuff[0],len); // 将待写入数据分成两部分
write_len=I2cWrite(FM24CL04_SecondPage,w_buff1,(len+1)); // 写入数据
}
if(write_len==(len+1))
return (write_len-1); // 返回实际读到的字节数
else
return 0;
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -