⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于zlg SmartARM2300平台的源码
💻 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 + -