历史上的今天
返回首页

历史上的今天

今天是:2024年08月23日(星期五)

正在发生

2019年08月23日 | STM32F407 纯寄存器操作GPIO,串口,中断(专治花里胡哨)

2019-08-23 来源:eefocus

配置时钟,延时函数,均使用正点原子的SYSTEM文件

硬件:正点原子探索者,STLINK调试


系统时钟配置步骤

**加粗样式**

正点原子,时钟配置函数(我都是直接把sys.c和sys.h拷贝过来,直接使用)


//设置向量表偏移地址

//NVIC_VectTab:基址

//Offset:偏移量  

void MY_NVIC_SetVectorTable(u32 NVIC_VectTab,u32 Offset)  

{       

SCB->VTOR=NVIC_VectTab|(Offset&(u32)0xFFFFFE00);//设置NVIC的向量表偏移寄存器,VTOR低9位保留,即[8:0]保留。

//时钟设置函数

//Fvco=Fs*(plln/pllm);

//Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));

//Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));


//Fvco:VCO频率

//Fsys:系统时钟频率

//Fusb:USB,SDIO,RNG等的时钟频率

//Fs:PLL输入时钟频率,可以是HSI,HSE等. 

//plln:主PLL倍频系数(PLL倍频),取值范围:64~432.

//pllm:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.

//pllp:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)

//pllq:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.


//外部晶振为8M的时候,推荐值:plln=336,pllm=8,pllp=2,pllq=7.

//得到:Fvco=8*(336/8)=336Mhz

//     Fsys=336/2=168Mhz

//     Fusb=336/7=48Mhz

//返回值:0,成功;1,失败。

u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq)

u16 retry=0;

u8 status=0;

RCC->CR|=1<<16; //HSE 开启 

while(((RCC->CR&(1<<17))==0)&&(retry<0X1FFF))retry++;//等待HSE RDY

if(retry==0X1FFF)status=1; //HSE无法就绪

else   

{

RCC->APB1ENR|=1<<28; //电源接口时钟使能

PWR->CR|=3<<14; //高性能模式,时钟可到168Mhz

RCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK 不分频;APB1 4分频;APB2 2分频. 

RCC->CR&=~(1<<24); //关闭主PLL

RCC->PLLCFGR=pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);//配置主PLL,PLL时钟源来自HSE

RCC->CR|=1<<24; //打开主PLL

while((RCC->CR&(1<<25))==0);//等待PLL准备好 

FLASH->ACR|=1<<8; //指令预取使能.

FLASH->ACR|=1<<9; //指令cache使能.

FLASH->ACR|=1<<10; //数据cache使能.

FLASH->ACR|=5<<0; //5个CPU等待周期. 

RCC->CFGR&=~(3<<0); //清零

RCC->CFGR|=2<<0; //选择主PLL作为系统时钟  

while((RCC->CFGR&(3<<2))!=(2<<2));//等待主PLL作为系统时钟成功. 

return status;

}  


//系统时钟初始化函数

//plln:主PLL倍频系数(PLL倍频),取值范围:64~432.

//pllm:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.

//pllp:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)

//pllq:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.

void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)

{  

RCC->CR|=0x00000001; //设置HISON,开启内部高速RC振荡

RCC->CFGR=0x00000000; //CFGR清零 

RCC->CR&=0xFEF6FFFF; //HSEON,CSSON,PLLON清零 

RCC->PLLCFGR=0x24003010; //PLLCFGR恢复复位值 

RCC->CR&=~(1<<18); //HSEBYP清零,外部晶振不旁路

RCC->CIR=0x00000000; //禁止RCC时钟中断 

Sys_Clock_Set(plln,pllm,pllp,pllq);//设置时钟 

//配置向量表   

#ifdef  VECT_TAB_RAM

MY_NVIC_SetVectorTable(1<<29,0x0);

#else   

MY_NVIC_SetVectorTable(0,0x0);

#endif 

}


时钟与外设

在这里插入图片描述

使能则相应位置一

image.png?imageView2/2/w/550


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


 RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟

 RCC->APB2ENR |= (1<<14);  //使能syscfg时钟



GPIO


在这里插入图片描述

设置步骤:


使能相关时钟


设置相应的IO口为输入或输出 BSRRH BSRRL


设置输入输出的类型 OTYPER


设置输出的速度(如果设置为输入,此步跳过) OSPEEDR


如果输出速度>=50M,开启补偿单元 SYSCFG->CMPCR


设置上拉下拉寄存器 PUPDR


注意:

IDR寄存器,(只读),对GPIO输入的读取

ODR寄存器,对GPIO输出的读写

BSSR寄存器,(只写),对GPIO输出,低16位,输出高电平,高16位,输出低电平

//reset register GPIOx_BSRRH, write only

//set register GPIOx_BSRRL, write only

在这里插入图片描述

GPIO F9,F10 交替闪烁


#include  

#include

#include

 

int main ()

{   

  Stm32_Clock_Init(336,8,2,7); //系统时钟

delay_init(48);

  

  RCC->AHB1ENR |= 0x00000020; //使能GPIOF时钟

  

  GPIOF->MODER &= 0x00000000; //设置F9,F10  0001 0100 0000 0000 0000 0000

  GPIOF->MODER |= 0x00140000; 

  

  GPIOF->OTYPER &= 0x00000600; //设置F9,F10推挽输出

  

  GPIOF->OSPEEDR &= 0x00000000; //F9,F10 速度50m 0010 1000 0000 0000 0000 0000

  GPIOF->OSPEEDR |= 0x00280000;

  

  

  //GPIOF->PUPDR &= 0x00280000;  //10下拉   00无   

//GPIOF->PUPDR &= 0x00140000;    //01上拉

  

  

  while(1)

  {

      GPIOF->BSRRH = 0x0200; //0000 0000 0010

  delay_ms(1000);

  GPIOF->BSRRL = 0x0200; //0000 0000 0010

   

      GPIOF->BSRRH = 0x0400; 

  delay_ms(1000);

  GPIOF->BSRRL = 0x0400; 

// GPIOF->ODR=0x00000600;

// delay_ms(1000);

// GPIOF->ODR=0x00000000;

// delay_ms(1000);


  }

}


串口与GPIO复用

GPIO复用功能映射表,只给出PORTA,B,C


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

根据表中找出对应外设的复用引脚,及复用功能选择位,AFn。


GPIO复用:

由两个寄存器控制,GPIOx_AFRH(高八位),GPIOx_AFRL(低八位)。

在程序中,GPIOB->AFR[0]表示GPIOx_AFRL(低八位),

GPIOB->AFR[1]表示GPIOx_AFRH(高八位)。


在这里插入图片描述
在这里插入图片描述

找到对应的引脚y,写入AFn。

比如串口三对应的复用功能是AF7,引脚是B10,11。则设置引脚的输出类型,速度,上拉下拉。

引脚位于高八位,写入GPIOx_AFRH,GPIOB->AFR[1] = 0x00007700


串口三 内容回显

内容以回车(0x0D)结束


设置步骤:


使能相关时钟

RCC->AHB1ENR|=1<<1;    //使能PORTB口时钟  

RCC->APB1ENR|=1<<18;  //使能串口3时钟 


设置相应的IO口为复用输出

GPIO_Set(GPIOB,PIN10|PIN11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PB10,PB11,复用功能,上拉输出

  GPIO_AF_Set(GPIOB,10,7); //PB10,AF7

GPIO_AF_Set(GPIOB,11,7); //PB11,AF7


波特率设置

//计算波特率

float temp;

u16 mantissa;

u16 fraction;    

temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV,OVER8设置为0

mantissa=temp;     //得到整数部分

fraction=(temp-mantissa)*16; //得到小数部分,OVER8设置为0  

   mantissa<<=4;

mantissa+=fraction; 


//串口设置

USART3->BRR=mantissa; //波特率设置  

USART3->CR1|=1<<3;  //串口发送使能  

USART3->CR1|=1<<2;  //串口接收使能

USART3->CR1|=1<<5;    //接收缓冲区非空中断使能

USART3->CR1|=1<<13;  //串口使能  


//中断优先级

MY_NVIC_Init(0,0,USART3_IRQn,2);//组2,优先级0,0,最高优先级 


状态寄存器 USART3->SR


数据寄存器 USART3->DR


缓冲区数组内容清空 memset(USART3_RX_BUF,0,USART3_MAX_RECV_LEN)


完整代码:


#include

#include

#include  

#include "string.h"

 

u8 ok_to_send; //可以发送的标志

u8 Rx_data_counter;


#define USART3_MAX_RECV_LEN 400 //最大接收缓存字节数


//串口接收缓存区

u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.


u8 Rx_data_counter=0;

u8 ok_to_send=0;


void USART3_IRQHandler(void)

{

  if(USART3->SR & (1<<5)) //接收数据寄存器非空

{

USART3_RX_BUF[Rx_data_counter] = USART3->DR;

Rx_data_counter++;

if(USART3_RX_BUF[Rx_data_counter-1] ==0x0D)

{

      Rx_data_counter = 0;

ok_to_send=1;

}

}  



//初始化IO 串口3

//pclk1:PCLK1时钟频率(Mhz)

//bound:波特率 


void usart3_init(u32 pclk1,u32 bound)

{   

float temp;

u16 mantissa;

u16 fraction;    

temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV,OVER8设置为0

mantissa=temp; //得到整数部分

fraction=(temp-mantissa)*16; //得到小数部分,OVER8设置为0  

  mantissa<<=4;

mantissa+=fraction; 

RCC->AHB1ENR|=1<<1;    //使能PORTB口时钟  

RCC->APB1ENR|=1<<18;  //使能串口3时钟 

GPIO_Set(GPIOB,PIN10|PIN11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PB10,PB11,复用功能,上拉输出

  GPIO_AF_Set(GPIOB,10,7); //PB10,AF7

GPIO_AF_Set(GPIOB,11,7); //PB11,AF7

//波特率设置

  USART3->BRR=mantissa; // 波特率设置  

USART3->CR1|=1<<3;  //串口发送使能  

USART3->CR1|=1<<2;  //串口接收使能

USART3->CR1|=1<<5;    //接收缓冲区非空中断使能

USART3->CR1|=1<<13;  //串口使能  

MY_NVIC_Init(0,0,USART3_IRQn,2);//组2,优先级0,0,最高优先级 

}


 

int main()


u8 j=0;


Stm32_Clock_Init(336,8,2,7); 


usart3_init(42,9600);//初始化串口3为:9600,波特率.


while(1)

if(ok_to_send==1)

{

for(j=0;j

USART3->DR=USART3_RX_BUF[j];

while((USART3->SR&0X40)==0);//循环发送,直到发送完毕 

if( USART3_RX_BUF[j] ==0x0D)

{

ok_to_send=0;

j=0;

memset(USART3_RX_BUF,0,USART3_MAX_RECV_LEN);

  }

    }

}

}

}


注意:

在这里插入图片描述

串口数据的读写,可以看到,是以8bit,一个字节为单位来读写的。利用DR寄存器,对DR进行读取,即DR赋值给别人,BUFF=DR。对DR进行写入,即别人赋值给DR,DR=BUFF。


再利用状态寄存器,SR来读取状态信息控制。


在这里插入图片描述

在这里插入图片描述

能否像小船博主一样,全部用寄存器来设置呢?

https://blog.csdn.net/w471176877/article/details/7957187


也就是关于GPIO复用


在这里插入图片描述
在这里插入图片描述

注释了GPIO设置的三个函数,完全用寄存器来设置


// GPIO_Set(GPIOB,PIN10|PIN11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PB10,PB11,复用功能,上拉输出

// GPIO_AF_Set(GPIOB,10,7); //PB10,AF7

// GPIO_AF_Set(GPIOB,11,7); //PB11,AF7

GPIOB->AFR[1] = 0x00007700;//选择PB10,11复用功能 

 

GPIOB->MODER &= 0xFF0FFFFF; //设置PB10,11,复用模式

GPIOB->MODER |= 0x00A00000; 



GPIOB->OSPEEDR &= 0xFFCFFFFF; //PB10速度50m

GPIOB->OSPEEDR |= 0x00200000;

 

GPIOB->PUPDR &= 0xFFCFFFFF; //PB10

GPIOB->PUPDR |= 0x00100000;


中断优先级函数也用寄存器来替代了


  //MY_NVIC_Init(0,0,USART3_IRQn,2);//组2,优先级0,0,最高优先级 

  SCB->AIRCR = 0x05FA0000 | 0x400;  //中断优先级分组 抢占:响应=3:1

NVIC->IP[39] = 0xf0; //最低抢占优先级,最低响应优先级1111

  NVIC->ISER[1] |= (1<<(39-32)); //使能中断线39,也就是usart3中断


除了时钟树配置,其它都自己用寄存器来配置了。


#include

#include

#include  

#include "string.h"

 

u8 suffer[100];

u8 ok_to_send;

u8 Rx_data_counter;


#define USART3_MAX_RECV_LEN 400 //最大接收缓存字节数


//串口接收缓存区

u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.


u8 Rx_data_counter=0;

u8 ok_to_send=0;


void USART3_IRQHandler(void)

{

  if(USART3->SR & (1<<5)) //接收数据寄存器非空

{

USART3_RX_BUF[Rx_data_counter] = USART3->DR;

Rx_data_counter++;

if(USART3_RX_BUF[Rx_data_counter-1] ==0x0D)

{

      Rx_data_counter = 0;

ok_to_send=1;

}

}  



//初始化IO 串口3

//pclk1:PCLK1时钟频率(Mhz)

//bound:波特率 


void usart3_init(u32 pclk1,u32 bound)

{   

float temp;

u16 mantissa;

u16 fraction;    

temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV,OVER8设置为0

mantissa=temp; //得到整数部分

fraction=(temp-mantissa)*16; //得到小数部分,OVER8设置为0  

  mantissa<<=4;

mantissa+=fraction; 

RCC->AHB1ENR|=1<<1;    //使能PORTB口时钟  

RCC->APB1ENR|=1<<18;  //使能串口3时钟 


GPIOB->AFR[1] = 0x00007700;//选择PB10,11复用功能 

 

GPIOB->MODER &= 0xFF0FFFFF; //设置PB10,11,复用模式

GPIOB->MODER |= 0x00A00000; 

推荐阅读

史海拾趣

Gamewell-FCI ( Honeywell )公司的发展小趣事

在电子行业中,Gamewell-FCI作为霍尼韦尔(Honeywell)旗下的重要品牌,其发展历程充满了诸多关键节点和里程碑事件。以下是五个与Gamewell-FCI(Honeywell)公司发展相关的故事,每个故事均基于事实描述:

1. Gamewell-FCI的起源与并入霍尼韦尔

Gamewell-FCI的起源可以追溯到其前身Gamewell Fire Alarm Telegraph Company,该公司成立于19世纪末,以生产创新的火灾报警系统而闻名。随着技术的不断进步和市场需求的扩大,Gamewell逐渐发展成为火灾安全领域的领导者。20世纪后期,Gamewell被FCI(Fire Control Instruments)收购,进一步巩固了其在消防报警技术领域的地位。随后,随着霍尼韦尔在工业自动化和安全领域的扩展,Gamewell-FCI被并入霍尼韦尔大家庭,成为其安全与生产力解决方案集团的一部分。这一合并不仅为Gamewell-FCI带来了更广阔的市场和资源,也使其能够继续推动消防安全技术的创新与发展。

2. 技术创新与产品线扩展

在并入霍尼韦尔后,Gamewell-FCI凭借其深厚的技术底蕴和创新能力,不断推出新产品和技术解决方案。从传统的火灾报警系统到先进的智能火灾探测和预警系统,Gamewell-FCI始终走在行业前列。公司还积极拓展产品线,涵盖了气体检测、紧急通讯、安全疏散等多个领域,为客户提供全方位的消防安全解决方案。这些技术创新和产品线扩展不仅增强了Gamewell-FCI的市场竞争力,也为其在全球范围内的业务扩展奠定了坚实基础。

3. 全球化布局与战略合作

随着全球化进程的加速,Gamewell-FCI也积极实施全球化战略,通过在全球各地设立分支机构、与当地企业建立合作关系等方式,不断扩大其市场覆盖面。同时,公司还注重与行业内的领军企业建立战略合作关系,共同推动消防安全技术的创新与发展。这些合作不仅为Gamewell-FCI带来了更多的商业机会,也促进了全球消防安全领域的交流与合作。

4. 应对市场挑战与转型

面对不断变化的市场环境和客户需求,Gamewell-FCI始终保持着敏锐的洞察力和灵活的反应能力。当传统消防安全市场逐渐饱和时,公司及时调整战略方向,将重心转向智能消防、物联网等新兴领域。通过引入先进的物联网技术、大数据分析等手段,Gamewell-FCI成功实现了从传统消防设备制造商向智能消防安全解决方案提供商的转型。这一转型不仅为公司带来了新的增长点,也为其在全球消防安全领域的领先地位提供了有力支撑。

5. 可持续发展与社会责任

作为霍尼韦尔的一部分,Gamewell-FCI始终将可持续发展和社会责任视为企业发展的重要组成部分。公司致力于通过技术创新和高效运营来降低产品对环境的影响,并积极推广节能减排、绿色建筑的理念。同时,Gamewell-FCI还积极参与社会公益事业,为灾区提供紧急救援、为教育机构提供安全培训等,展现了其作为行业领导者的社会责任感。这些努力不仅提升了公司的品牌形象和社会声誉,也为公司的长远发展奠定了坚实基础。

Akros[台湾超硕股份有限公司]公司的发展小趣事

面对日益激烈的市场竞争,Akros公司积极寻求市场拓展的机会。公司开始参加国际电子展会,与全球各地的客户建立联系。通过展示其独特的技术优势和高质量的产品,Akros逐渐赢得了国际市场的认可。同时,公司还加强了与全球供应链的合作,实现了原材料的全球化采购,降低了生产成本,提高了产品的竞争力。

常州星海电子(Starsea)公司的发展小趣事

在拓展国内市场的同时,常州星海电子也积极开拓国际市场。公司的产品主要销往欧洲地区、美国和亚洲各国,是MOTOROLA、YAMAHA、Samsung、VTECH、LG、NOKIA等跨国公司的二极管供应厂家。国外销售量占公司总销售量的60%以上,这一成绩不仅体现了公司在国际市场上的竞争力,也为公司未来的发展奠定了坚实的基础。

Axiohm公司的发展小趣事

随着国内市场的饱和,Axiohm公司开始寻求国际化发展。公司制定了详细的国际化战略,先后在亚洲、欧洲和北美设立了分支机构和研发中心。通过与当地企业的合作,Axiohm成功打入多个国际市场,并根据不同地区的需求进行产品定制。这一战略不仅拓宽了公司的销售渠道,还提升了品牌知名度。

Elite Enterprises (H K) Co Ltd公司的发展小趣事

随着市场的竞争加剧,Elite Enterprises意识到只有不断提升产品品质和技术水平,才能在竞争中立于不败之地。因此,公司加大了对研发的投资,不断引进先进的生产设备和检测仪器,并严格把控原材料采购和生产流程。这些努力使公司的LED产品在光效、寿命和稳定性等方面均达到了行业领先水平。

BERNSTEIN公司的发展小趣事

在BERNSTEIN公司的发展过程中,家族传承和企业管理一直是一个重要的主题。Hans-Joachim Bernstein作为Hans Bernstein的长子,在塑造公司的成功故事中发挥了重要作用。在他的管理下,“SpezialFabrik für Schaltkontakte”公司发展成为当今在国际上活跃的技术集团。这家家族企业现已进入第三代,Nicole和Achim Bernstein作为新一代领导人,继续传承着家族的优良传统和企业文化,推动着公司的持续发展。

问答坊 | AI 解惑

软件、硬件、PCB设计的QQ群

欢迎各位软件高手到,软件、硬件、PCB设计的QQ群:63147422 讨论…

查看全部问答>

青越锋软件的常见操作问题----(PCB)

1、对于你们软件中的“Import”、“Open”这两个菜单的命名,我不是很能理解,能说说吗? 答:Open 是指打开我们的软件保存的文件,而Import是指导入其他软件转换的ASCII文件。 2、怎么我找不到网络编辑的菜单啊? 答:我们的网络编辑更加快捷 ...…

查看全部问答>

船用无线电设备图纸(JRC)

[ 本帖最后由 zcgzanne 于 2009-11-13 22:25 编辑 ]…

查看全部问答>

at91sam7s64的 原理图和pcb,供布线参考。

这个板子有点小问题。 1.xout部分当clk不能用,飞线到pclk,管脚。原因:xout信号太弱。所以,咱这个stm32的xout部分就去掉吧。 2.spck接a3p060 pin91不行,那不是全局管脚,2,4,6  93,94可以,我用的93. 3.12 - 5 v的DC-dc不能用,有 ...…

查看全部问答>

CE正在用MediaPlayer播音乐,手动休眠再唤醒后就没音乐了!但点击屏幕还有声音

如题,是怎么回事啊? 在串口里会输出 +-BattHwPowerOn() I2CWrite ERROR: 170 I2CWrite ERROR: 170 I2CWrite ERROR: 170 I2CWrite ERROR: 170 I2CWrite ERROR: 170 I2CWrite ERROR: 170 等信息, I2CWrite ERROR在WaveDev的hwctxt.cpp的HW_ ...…

查看全部问答>

第一次进win ce 几个起步问题

第一次进wince模块,问几个问题 1 把win ce 嵌入到像ARM9平台上,那么wince 这个软件价格怎样?像蛮多做实验板的开发商提供的一些软件包就以用了吗?如果真做成了一个产品,是基于wince OS的,那么这个需要正式向微软件购买使用版权费吗? 2 wince 嵌入 ...…

查看全部问答>

【高分求助】关于ARMV6的仿真

我使用的是RVDS2.2. 在编译设置选项里设置只要我选择ARMV6系列的芯片,编译连结可以通过,但DEBUG(运行)的时候GO MAIN就会出错,提示有未定义的指令。而只要选择V6以下的芯片,都是好着的。 编译的程序很简单,就是一个MAIN函数。 请高手指点一 ...…

查看全部问答>

最新TI C2000 系列技术研讨会 时间安排

TI C2000 系列技术研讨会 C2000 器件是具有高性能集成外设(针对实时控制应用而设计)的 32 位微处理器。它的数学优化内核使设计人员能够提高系统效率、可靠性和灵活性。功能强大的集成外设使 C2000 器件成为最理想的单芯片控制解决方 ...…

查看全部问答>

为什么ti的邮箱验证页无法进入?

ti样片中心更新后,说我的帐号要重新验证,点了之后过了一会儿总是连接被阻断,根本进不去,怎么回事?…

查看全部问答>

在这里支持一下“一步一步教你用UCOS”给大家推荐三本好书

在这里给大家推荐三本学习ucos的必看书籍   1.(比较难买)嵌入式实时操作系统uc/os-II教程  西安电子科技大学出版 -----这本书对UCOS的源代码分析的非常清楚 比作者原著          &nbs ...…

查看全部问答>