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

📄 main.cpp

📁 USB中文数据说明
💻 CPP
📖 第 1 页 / 共 3 页
字号:

//inline
void UartObj::putchar(unsigned char dat)
{
  U0->THR = dat;
  while ((U0->LSR & (1 << TEMT)) == 0);// 等待数据发送完毕
}

//inline
void UartObj::putstr(const char str[])
{
  while (*str) {
	putchar(*str);
	str++;
  }
}


//inline
void UartObj::puts(const char str[])
{
  while (*str) {
	putchar(*str);
	str++;
  }
  putchar(0x0d);
  putchar(0x0a);//回车换行
}

//__inline
TwiObj::TwiObj(void)
{
  TwiInit();
}

void TwiObj::TwiInit(void)
{
  PINSEL->PIN_SEL0 |= (P0_2_SCL0 << P0_2_PINSEL) | (P0_3_SDA0 << P0_3_PINSEL);
  I2C0->I2C_CONCLR = (1 << STAC) | (1 << SIC) | (1 << AAC);

//  I2CPORT->IODIR   |= (1 << SDA) | (1 << SCL);
//  I2CPORT->IOSET    = (1 << SDA);
//  I2CPORT->IOSET    = (1 << SCL);
  I2C0->I2C_SCLH = (Fpclk / Fi2c + 1) /2;
  I2C0->I2C_SCLL = (Fpclk / Fi2c) /2;
  I2C0->I2C_CONCLR = (1 << STA) | (1 << SI);
  I2C0->I2C_CONSET = (1 << I2EN);
  
  Count = 0;
}

void TwiObj::TWStart(void)
{
  Busy = true;
  Status = 0;//主机准备发送启始位
  Count = 0;//发送数据个数
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STA);
}

void TwiObj::TWREStart(void)
{
  Busy = true;
  Status = 0x55;//主机准备发送启始位
  Count = 0;//接收数据个数
  I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STA);
}

//__inline
void TwiObj::TWStop(void)
{
  Busy = false;
  Status = 0x88;//通讯成功
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STO);
  I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);
}

void TwiObj::TWExit(void)
{
  Busy = false;
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STO);
  I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);
}

void TwiObj::Exec(void)
{
//char str[64];
//int I2C_STAT;
//I2C_STAT = I2C0->I2C_STAT;
  switch(I2C0->I2C_STAT & 0xf8) {//测试5位状态码
    case I2C_START://主机收到自己发送的开始信号
	       if (Status == 0) {//本次中断是在调用TWStart()函数后引发的
	         I2C0->I2C_DAT = SubAddr & 0xfe;//发送从机机地址(强行设置写操作)
			 Status = 1;//Status下次主发为1,主收为2。准备进入主发模式
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
		   }
		   else TWExit();//本次中断不是在调用TWStart()函数后引发的
	       break;
	case I2C_REP_START://主机收到自己发送的重新开始信号
	       if ((Status == 0x55) && (SubAddr & 0xfe)) {//本次中断是在调用TWREStart()函数后引发的
	         I2C0->I2C_DAT = SubAddr;//发送从机地址(本次中断必须是读操作)
		     Status = 2;//Status下次主发为1,主收为2。准备进入主收模式
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
		   }
		   else TWExit();//本次中断不是在调用TWREStart()函数或不为读操作后引发的
	       break;
	case I2C_MT_SLA_ACK://主发机接收到从机的地址应答信号后发送命令
	       if (Status == 1) {//本次中断应该在发送从机地址写操作后引发
		     Status = 3;//Status下次应该收TW_MT_DATA_ACK
             I2C0->I2C_DAT = SubComm;//发送子机命令
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
		   }
		   else TWExit();//本次中断不是在发送从机地址写操作后引发
	       break;
	case I2C_MR_SLA_ACK://主收机接收到从机的地址应答信号
	       if (SubCount && (Status == 2)) {//本次中断应该接收I2C_MR_SLA_ACK信号
		     Status = 4;//Status下次应该收I2C_MR_DATA_ACK
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI);//清除中断标志
			 I2C0->I2C_CONSET = (1 << AA);//主机向从机发送应答信号?????????
		   }
		   else TWExit();
		   break;
	case I2C_MT_DATA_ACK:
	       if ((Count < MainCount) && (Status == 3)) {//本次中断应该接收TW_MT_DATA_ACK信号
//	       if ((Count < MainCount) && (Status == 3) && ((SubAddr & 1) == 0)) {//本次中断应该接收TW_MT_DATA_ACK信号
	         I2C0->I2C_DAT = TxBuffer[Count ++];//发送子机数据
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
		   }
		   else {
	         if ((SubCount > 0) && (Status == 3) && (SubAddr & 1)) {//本次中断应该接收TW_MT_DATA_ACK信号
		       TWREStart();//
//  Uart.puts("TWREStart()");
			 }
             else TWExit();
		   }
		   break;
//	case I2C_MT_DATA_NACK://数据发送结束
//	       if ((Count == MainCount) && (Status == 4)) {
//             TW_Error = 0xf0;//数据发送失败
//		   }
//		   TWStop();
//		   break;
	case I2C_MR_DATA_ACK:
	       if ((Count < SubCount) && (Status == 4)) {
	         RxBuffer[Count ++] = I2C0->I2C_DAT;//接收子机数据
			 if (Count < SubCount) {
               I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//主机转入接收状态
			   I2C0->I2C_CONSET = (1 << AA);//主机向从机发送应答信号
			 }
			 else {//最后一个接收数据主机不向从机发送应答信号
               I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志,主机转入接收状态
			 }
//			 sprintf(str, "RxBuffer[%02d]=%02X", Count -	1, RxBuffer[Count - 1]);
//			 Uart.puts(str);
		   }
		   else TWExit();
		   break;
	case I2C_MR_DATA_NACK://数据接收结束
	      if ((Count == SubCount) && (Status == 4)) {
		     TWStop();//正常结束
//  Uart.puts("TWStop()");
		   }
		   else TWExit();
		   break;
	default://其他状态认为通讯失败
		   TWExit();
  }
//  sprintf(str, "I2C0->I2C_STAT=%02X  TWIStatus=%04d Count=%04d", I2C_STAT, Status, Count);
//  Uart.puts(str);
}

void TwiObj::TWByteWrite(unsigned int addr, unsigned int cnt)
{
  MainCount = cnt;//发送数据
  SubCount = 0;//接收数据
  SubComm = addr;
  SubAddr = 0xa1;
  TWStart();
  while (Busy);
}

void TwiObj::TWByteRead(unsigned int addr, unsigned int cnt)
{
  MainCount = 0;//发送数据
  SubCount = cnt;//接收数据
  SubComm = addr;
  SubAddr = 0xa1;
  TWStart();
  while(Busy);
}


void TwiObj::WorkExec(void)
{
	for(int i = 0; i < 16;i ++) {
	  TxBuffer[i] = 16 + i;
	}
  SubCount = 0;//接收0个数据
  MainCount = 0;//发送0个数据
  SubComm = 0;
  if (Busy) {
    TWStop();
//::Uart.puts("TW_Busy");
  }
  else {
//
    SubAddr = 0xa1;
	SubCount = 10;//接收4个数据
	SubComm = 0;
    MainCount = 6;//10;//发送0个数据
	for(int i = 0; i < 10;i ++) {
	  RxBuffer[i] = 0;
	}
//
/*
I2C0->I2C_STAT=08  TWIStatus=0001 Count=0000
I2C0->I2C_STAT=18  TWIStatus=0003 Count=0000
TWREStart()
I2C0->I2C_STAT=28  TWIStatus=0085 Count=0000
I2C0->I2C_STAT=10  TWIStatus=0002 Count=0000
I2C0->I2C_STAT=40  TWIStatus=0004 Count=0000
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0001
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0002
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0003
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0004
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0005
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0006
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0007
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0008
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0009
I2C0->I2C_STAT=50  TWIStatus=0004 Count=0010
I2C0->I2C_STAT=58  TWIStatus=0004 Count=0010


*/
//////////////////////////////////////////
/*
    SubAddr = 0xa0;
	SubCount = 0;//接收4个数据
	SubComm = 0;//字节地址
    MainCount = 10;//10;//发送0个数据
	for(int i = 0; i < 10;i ++) {
	  TxBuffer[i] = 10 + i;
	}
*/
/*

I2C0->I2C_STAT=08  TWIStatus=0001 Count=0000
I2C0->I2C_STAT=18  TWIStatus=0003 Count=0000
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0001
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0002
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0003
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0004
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0005
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0006
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0007
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0008
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0009
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0010
I2C0->I2C_STAT=28  TWIStatus=0003 Count=0010

*/
//////////////////////////////////////////
//    SubAddr = 0xa1;
//	SubCount = 10;//接收4个数据
//	SubComm = 1;
//    MainCount = 10;//10;//发送0个数据
	TWStart();
  }  
}

IapObj::IapObj(void)
{
  IapInit();
//  IapWriteTest();
}

void IapObj::IapInit(void)
{
}

void IapObj::IapWriteTest(void)
{
char str[64];
unsigned char a[256];//ram
unsigned char *ptr;
int i;
  ptr = (unsigned char *)0x000010000;//flash 
  Uart.puts("");
  if (EraseSector(ptr, (void *)0x000100ff)) {
    Uart.puts("擦除成功!!!");
  }
  else {
    Uart.puts("擦除失败!!!");
  }
  for (i = 0; i < 256; i ++) {
    a[i] = *(ptr + i);
  }
//  for (i = 128; i < 256; i ++) {
//    a[i] = (unsigned char)i;
//  }
  Uart.puts("");
  for (i = 0; i < 256; i ++) {
    a[i] = (unsigned char)i;
    if (ProgramPage(ptr, (void *)&a[0], 256)){ 
      sprintf(str, "%02X -->一次写入成功!!!", i);
      Uart.puts(str);
	}
	else {
      sprintf(str, "%02X -->一次写入失败!!!", i);
      Uart.puts(str);
	}
  }
  Uart.puts("");
  for (i = 0; i < 256; i ++) {
    sprintf(str, "%02X: %02X", i, *(ptr + i));
    Uart.puts(str);
  }
  Uart.puts("");
  for (i = 0; i < 4; i ++) {//对0xfe进行二次写入,写4遍后为0xaa
    a[254] &= ~(1 << (i * 2));
    if (ProgramPage(ptr, (void *)&a[0], 256)){
      sprintf(str, "%02X -->二次写入成功!!!", a[254]);
      Uart.puts(str);
	}
	else {
      sprintf(str, "%02X -->二次写入失败!!!", a[254]);
      Uart.puts(str);
	}
  }
  Uart.puts("");
  for (i = 0; i < 8; i ++) {//对0xff进行二次写入,写8遍后为0x00
//    a[255] &= ~(1 << i);//等效为下句
    a[255] <<= 1;
    if (ProgramPage(ptr, (void *)&a[0], 256)){
      sprintf(str, "%02X -->二次写入成功!!!", a[255]);
      Uart.puts(str);
	}
	else {
      sprintf(str, "%02X -->二次写入失败!!!", a[255]);
      Uart.puts(str);
	}
  }
}

typedef void (* IAPPV)(LPCS_IAPDATA &, unsigned int *);//一般函数指针
#define IAP_ENTER_ADR   0x7FFFFFF1  // IAP入口地址定义

bool IapObj::IapExec(void)
{
unsigned int save_VicInt;                // for saving of interrupt enable register
bool result;
/* 定义函数指针 */
//void (*IAP_Entry)(LPCS_IAPDATA &);
  save_VicInt = VIC->IntEnable;              // save interrupt enable status
  VIC->IntEnClr = 0xFFFFFFFF;                // disable all interrupts
IAPPV IAP_Entry = reinterpret_cast<IAPPV>(IAP_ENTER_ADR);
  IAP_Entry(IAPDR, &IAPDR.stat);// 调用IAP服务程序
//  iap_execute(IAPDR);// 调用IAP服务程序
  VIC->IntEnable = save_VicInt;              // enable interrupts
  result = (IAPDR.stat == CMD_SUCCESS);
  return result;
}

unsigned int IapObj::GetSecNum (void *adr)
{
unsigned int n;
  n = ((unsigned int)adr >> 12) & 0x7F;                      // Pseudo Sector Number
  if (n >= 0x78) {                             // High Small 4kB Sectors
    n -= 0x62;
  } 
  else if (n >= 0x08) {                        // Large 32kB Sectors
    n  = 0x07 + (n >> 3);
  }

  return (n);                                  // Sector Number
}

bool IapObj::SelSector(void* start, void* end)
{
bool result;
  IAPDR.cmd = IAP_SELECTOR;//选择扇区
  IAPDR.par[0] = GetSecNum(start);//开始扇区
  IAPDR.par[1] = GetSecNum(end);  //结束扇区
  IapExec();// 调用IAP服务程序
  result = (IAPDR.stat == CMD_SUCCESS);
  return result;
}

bool IapObj::EraseSector(void* start, void* end)
{
bool result;
  result = SelSector(start, end);
  if (result) {
    IAPDR.cmd = IAP_ERASESECTOR;//擦除扇区
    IAPDR.par[2] = IAP_FCCLK;
    IapExec();// 调用IAP服务程序
    result = (IAPDR.stat == CMD_SUCCESS);
  }
  return result;
}

bool IapObj::ProgramPage(void * flash, void * ram, unsigned int size)
{
bool result = false;
  size &= 0xfffffffc;//必须是32位4个字节
  if (size) {
/*
    IAPDR.cmd = IAP_SELECTOR;//选择扇区
    IAPDR.par[0] = GetSecNum(flash);//目的扇区
    IAPDR.par[1] = IAPDR.par[0];//GetSecNum((void *)((unsigned int)flash + (size - 1)));  //源扇区
    IapExec();// 调用IAP服务程序
    result = (IAPDR.stat == CMD_SUCCESS);
*/
    result = SelSector(flash, (void *)((int)flash + size - 1));
    if (result) {
      IAPDR.cmd = IAP_RAMTOFLASH;//拷贝数据
      IAPDR.par[0] = (unsigned int)flash; //写入数据字节的目标Flash地址。目标地址的边界应当为256字节为边界。
      IAPDR.par[1] = (unsigned int)ram;//读出数据字节的源RAM地址。该地址应当以字为边界。
	  IAPDR.par[2] = size;//写入字节的数目。应当为256/512/1024/4096.
      IAPDR.par[3] = IAP_FCCLK;//系统时钟频率(CCLK)(单位:KHz)
      IapExec();//调用IAP服务程序
      result = (IAPDR.stat == CMD_SUCCESS);
    }
  }
  return result;
}

/*----------------------------------------------------------------------------
 *        Main: Initialize and start ARTX Kernel
 *---------------------------------------------------------------------------*/
int main (void) {                    /* program execution starts here       */
  Enable_IRQ();//开中断
  os_sys_init (MainTask);//启动ARTX,此函数并不返回main()
}

/*----------------------------------------------------------------------------
 * end of file
 *---------------------------------------------------------------------------*/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -