[关闭]
@floatsd 2016-01-02T12:38:04.000000Z 字数 23774 阅读 1069

CM4实验报告

CM4实验报告


范璐 自动化1302 201303080207


前言

  • 我觉得给那块板子拍照是件比较愚蠢的事情,主要是时间花的不值得,毕竟验收的时候已经看过了。而且,虽然每个模块的函数独立而且各司其职,但是主要是每次的①主函数和②中断向量中断优先级中断使能等中断相关③文件包含关系都要改一些东西。如果要依次再把之前的实验都做一遍,意味着要多次改整个的那个项目,修改东西往往比加东西要来的复杂和蛋疼。因为改东西有时候,改着改着,就不对了。出于以上担忧,我决定不拍板子跑程序的效果照片并对做了这项工作的同学报以崇高的敬意。
  • 接触到的第一个例程是@zxk的例程是一件幸运的事,从一开始就养成了一些比较能够提高效率的编程习惯。@zxk的教学基本都是干货,在对每次要用的模块长什么样有个概念的前提下,他的讲解清晰易懂,并且会补充一些实用的细节,为快速入门之佳品,在此对助教表达感谢。
  • 后几个实验难度其实比较大,但是学长已经做好了大部分工作,几乎相当于已经编写了一套库函数出来,我们只要使用即可,大大的减轻了实验难度和我们的工作量。
  • 使用的在线编辑器基于markdown语言,很方便,就是没法空行或者打空格。导出PDF时的分页因此变得无法控制,丑的不忍直视。

实验一 GPIO流水灯

1.1实验目的

  • 把CCS安装好,熟悉CCS操作,编译界面
  • 创建工程,开始学习TM4C1294软件开发过程
  • 了解GPIO的概念,学会查找端口功能,调用GPIO库函数让LED跑起来

1.2实验原理

1.2.1系统时钟

  1. /*******************************************************************
  2. * 函数: Clock_Init()
  3. * 描述: 配置使能系统时钟
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void Clock_Init(){
  8. SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |//外部时钟25MHz
  9. SYSCTL_OSC_MAIN |//OSC时钟源选择主振荡器作为OSC
  10. SYSCTL_USE_PLL |//采用锁相环PLL作为系统时钟源
  11. SYSCTL_CFG_VCO_480), //压控振荡器频率480MHz
  12. sysClock_Fr);//设定系统频率为sysClock_Fr
  13. }

1.2.2GPIO

信号 端口 信号 端口
LED0 PF1 LED1 PF2
LED2 PF3 LED3 PL0
LED4 PL1 LED5 PL2
LED6 PL3 LED7 PL4
  1. /*******************************************************************
  2. * 函数: LED_Init()
  3. * 描述: LED的配置及初始化
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void LED_Init()
  8. {
  9. //使能GPIOF和GPIOL模块
  10. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
  11. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
  12. //将8盏LED配置为输出模式(GPIO管脚方向)
  13. GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
  14. GPIOPinTypeGPIOOutput(GPIO_PORTL_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
  15. }

1.3实现功能

1.4实验代码

  1. /*******************************************************************
  2. * 函数: LED_ON(uint8_t NumLED)
  3. * 描述: 点亮某一盏LED灯
  4. * 输入值:uint8_t NumLED
  5. * 返回值:无
  6. *****************************************************************/
  7. void LED_ON(uint8_t NumLED){
  8. switch(NumLED){
  9. case 0: GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1);break;
  10. case 1: GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2,GPIO_PIN_2);break;
  11. case 2: GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,GPIO_PIN_3);break;
  12. case 3: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_0,GPIO_PIN_0);break;
  13. case 4:GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_1,GPIO_PIN_1);break;
  14. case 5: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_2,GPIO_PIN_2);break;
  15. case 6: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_3,GPIO_PIN_3);break;
  16. case 7: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_4,GPIO_PIN_4);break;
  17. default: ledclose();break; //让所有灯灭的一个函数
  18. }}
  1. /*******************************************************************
  2. * 函数: LED_OFF(uint8_t NumLED)
  3. * 描述: 不亮某一盏LED灯
  4. * 输入值:uint8_t NumLED
  5. * 返回值:无
  6. *****************************************************************/
  7. void LED_OFF(uint8_t NumLED){
  8. switch(NumLED){
  9. case 0: GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,0x00);break;
  10. case 1: GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2,0x00);break;
  11. case 2: GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,0x00);break;
  12. case 3: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_0,0x00);break;
  13. case 4: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_1,0x00);break;
  14. case 5: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_2,0x00);break;
  15. case 6: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_3,0x00);break;
  16. case 7: GPIOPinWrite(GPIO_PORTL_BASE,GPIO_PIN_4,0x00);break;
  17. default: ledclose();break; //让所有等灭的一个函数
  18. }}
  1. /*******************************************************************
  2. * 函数: Delay(uint32_t CountMs)
  3. * 描述: 延时
  4. * 输入值: uint32_t CountMs
  5. * 返回值: 无
  6. *****************************************************************/
  7. void Delay(uint32_t CountMs){
  8. SysCtlDelay(CountMs*sysClock_Fr/3000);
  9. }

1.5实验结论

  1. void GPIOPin Type ADC (uint32_t ui32Port, uint8_t ui8Pins)
  2. void GPIOPin Type CAN (uint32_t ui32Port, uint8_t ui8Pins)
  3. void GPIOPin Type CIR (uint32_t ui32Port, uint8_t ui8Pins)
  4. void GPIOPin Type Comparator
  5. void GPIOPin Type EPI
  6. void GPIOPin Type Ethernet LED
  7. void GPIOPin Type Ethernet MII
  8. void GPIOPin Type GPIOInput
  9. void GPIOPin Type GPIOOutput

实验二 矩阵按键

2.1实验目的

  • 熟悉和掌握矩阵式键盘的工作原理、电路设计和软件编程方法。
  • 熟悉和掌握矩阵键盘的行列扫描法

2.2实验原理

信号 端口 信号 端口
ROW1_IN PP2 COL1_OUT PD1
ROW2_IN PN3 COL2_OUT PH3
ROW3_IN PN2 COL3_OUT PH2
ROW4_IN PD0 COL4_OUT PM3
Created with Raphaël 2.1.2Start列循环低电平扫描行值有键按下确定是哪个键调用对应程序Endyesno

2.3实现功能

2.4实验代码

2.4.1矩阵按钮初始化

  1. /*******************************************************************
  2. * 函数: Toggle_Init()
  3. * 描述: 配置使能矩阵按钮gpio口
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void Toggle_Init()
  8. {
  9. //使能引脚
  10. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
  11. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
  12. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
  13. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
  14. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
  15. //输入配置
  16. GPIOPinTypeGPIOInput(GPIOP, GPIO_PIN_2);
  17. GPIOPinTypeGPIOInput(GPION, GPIO_PIN_2|GPIO_PIN_3);
  18. GPIOPinTypeGPIOInput(GPIOD, GPIO_PIN_0);
  19. //输出配置
  20. GPIOPinTypeGPIOOutput(GPIOD, GPIO_PIN_1);
  21. GPIOPinTypeGPIOOutput(GPIOH, GPIO_PIN_2|GPIO_PIN_3);
  22. GPIOPinTypeGPIOOutput(GPIOM, GPIO_PIN_3);
  23. //设置行都为高电平,列为低电平
  24. R1h();
  25. R2h();
  26. R3h();
  27. R4h();
  28. C1l();
  29. C2l();
  30. C3l();
  31. C4l();
  32. }

2.4.2按键扫描函数

  1. /*******************************************************************
  2. * 函数: Row_Scan()
  3. * 描述: 扫描行或列返回电平被拉低的行/列
  4. * 输入值:无
  5. * 返回值:uint8_t
  6. *****************************************************************/
  7. uint8_t Row_Scan(){
  8. uint8_t r0,r1,r2,r3;
  9. r0 = GPIOPinRead(GPIOP, GPIO_PIN_2);
  10. r1 = GPIOPinRead(GPION, GPIO_PIN_2);
  11. r2 = GPIOPinRead(GPION, GPIO_PIN_3);
  12. r3 = GPIOPinRead(GPIOD, GPIO_PIN_0);
  13. if(r0==0x00){
  14. return 0;
  15. }
  16. else if(r1==0x00){
  17. return 1;
  18. }
  19. else if(r2==0x00){
  20. return 2;
  21. }
  22. else if(r3==0x00){
  23. return 3;
  24. }
  25. else return 4;
  26. }

2.4.3识别哪一行按键按下

  1. /*******************************************************************
  2. * 函数: Toggle_Loop()
  3. * 描述: 这里做的是检测被按下的行,本来是套了两个Row_Scan分别检测行列
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void Toggle_Loop(){
  8. ledclose();
  9. while(true){
  10. switch(Row_Scan()){
  11. case 0:led0(); break;
  12. case 1:led2(); break;
  13. case 2:led4(); break;
  14. case 3:ledrun(1); break;
  15. default:ledclose();break;
  16. }Delay(24);
  17. }
  18. }

2.5实验结论

实验三 PWM呼吸灯

3.1实验目的

  • 熟悉和掌握PWM模块的工作原理、模块结构和软件编程方法。
  • 学会调整输出周期和占空比

3.2实验原理

Created with Raphaël 2.1.2Start初始化PWM相关GPIO配置配置PWM工作时钟配置PWM发生器工作方式设置PWM频率与占空比使能PWM输出End

3.3实现功能

3.4实验代码

3.4.1PWM模块初始化

  1. /*******************************************************************
  2. * 函数: PWM_Init()
  3. * 描述: PWM初始化
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void PWM_Init()
  8. {
  9. SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
  10. PWMGenConfigure(PWM0_BASE, PWM_GEN_0|PWM_GEN_1,PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
  11. //配置系统时钟和配置重载值(如蜂鸣器,要注意范围2khz-4khz)
  12. PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0|PWM_GEN_1, 10000);
  13. PWMPulseWidthSet(PWM0_BASE,PWM_OUT_1|PWM_OUT_2|PWM_OUT_3|PWM_OUT_4|PWM_OUT_5|PWM_OUT_6|PWM_OUT_7|PWM_OUT_0,50);
  14. //PWM输出使能
  15. PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT |PWM_OUT_1_BIT |PWM_OUT_2_BIT | PWM_OUT_3_BIT, true);
  16. //PWM把发生器使能
  17. PWMGenEnable(PWM0_BASE, PWM_GEN_0);
  18. PWMGenEnable(PWM0_BASE, PWM_GEN_1);
  19. }

3.4.2呼吸灯实现

  1. /*******************************************************************
  2. * 函数: breathLED_run()
  3. * 描述: 使呼吸灯闪烁,这里用循环让占空比从变大到变小,再利用PWMPulseWidthSet() 每次循环改变占空比形成亮灭。
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void breathLED_run(){
  8. while(1)
  9. {
  10. for(ui32Loop=0;ui32Loop<1000;ui32Loop++)
  11. {
  12. ;
  13. }
  14. PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1,PWMPulseWidth);
  15. PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2,PWMPulseWidth);
  16. PWMPulseWidthSet(PWM0_BASE, PWM_OUT_3,PWMPulseWidth);
  17. PWMPulseWidth += flip;
  18. if(PWMPulseWidth >= 9990)
  19. {
  20. flip = -5;
  21. }
  22. else if(PWMPulseWidth <= 50)
  23. {
  24. flip = 5;
  25. }
  26. }
  27. }

3.5遇到的问题和解决办法

3.6实验结论

实验四 中断

4.1实验目的

  • 了解单片机里中断的概念。
  • 懂得声明中断向量,中断函数,改变中断优先级,最终学会使用中断。

4.2实验原理

4.3实现功能

4.4实验代码

4.4.1中断的配置及初始化

  1. /*******************************************************************
  2. * 函数: Handler_Init()
  3. * 描述: 开启中断
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void Handler_Init()
  8. {
  9. SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPIOD);
  10. //矩阵按键第四行
  11. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
  12. GPIOPinTypeGPIOInput(GPIO_PORTD_BASE,GPIO_PIN_0);
  13. GPIOIntTypeSet(GPIO_PORTD_BASE,GPIO_PIN_0,GPIO_LOW_LEVEL);
  14. GPIOIntEnable(GPIO_PORTD_BASE,GPIO_INT_PIN_0);
  15. //定时器
  16. SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
  17. TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC);
  18. TimerIntEnable(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
  19. TimerEnable(TIMER0_BASE, TIMER_B);
  20. TimerLoadSet(TIMER0_BASE, TIMER_B, sysClock_Fr/2000 );
  21. //优先级设置,如下所示,优先级越高数字上越小
  22. IntPrioritySet(INT_GPIOD,0x20);
  23. IntPrioritySet(INT_TIMER0B,0x00);
  24. IntEnable(INT_GPIOD); //开启相应中断向量
  25. /*3.开启总中断*/
  26. IntMasterEnable();
  27. }

4.4.2呼吸灯实现

  1. /*******************************************************************
  2. * 函数: GPIOD_Handler()
  3. * 描述: 矩阵按键第四行的中断函数
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void GPIOD_Handler()
  8. {
  9. uint32_t Status;
  10. Status=GPIOIntStatus(GPIO_PORTD_BASE,true);
  11. if(Status==GPIO_INT_PIN_0)
  12. {
  13. ledclose();
  14. //ledon(0);
  15. }
  16. GPIOIntClear(GPIO_PORTD_BASE,Status);
  17. }

4.4.3Timer的中断函数

  1. /*******************************************************************
  2. * 函数: GPIOD_Handler()
  3. * 描述: 利用Timer实现一毫秒扫描一次键盘减轻cpu负担
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void Timer_Handler(){
  8. unsigned long status;
  9. status=TimerIntStatus(TIMER0_BASE,true);
  10. if(status==TIMER_TIMB_TIMEOUT)
  11. {
  12. counter++;
  13. if(counter==10)
  14. {
  15. counter=1;
  16. switch(Row_Scan()){
  17. case 0:{
  18. LED_ON(1);Delay(24); break;
  19. }
  20. case 1:{
  21. LED_ON(2);Delay(24); break;
  22. }
  23. case 2:{
  24. LED_ON(3);Delay(24); break;
  25. }
  26. case 3:{
  27. LED_ON(4);Delay(24); break;
  28. }
  29. default:ledclose(); break;
  30. }
  31. }
  32. TimerIntClear(TIMER0_BASE, TIMER_TIMB_TIMEOUT);
  33. }
  34. }

4.5遇到的问题和解决办法

4.6实验结论

实验五 和米字管

5.1实验目的

  • 了解总线通信原理
  • 学会用C语言模拟时序
  • 学会查找和利用板子上的资源,控制米字管

5..2实验原理

5.2.1

  • 发送器:本次传送中发送数据(不包括地址和命令)到总线的器件。
  • 接收器:本次传送中从总线接收数据(不包括地址和命令)的器件。
  • 主机:初始化发送,产生时钟信号和终止发送的器件,它可以是发送器或接收器,主机通常是微控制器。
  • 从机:被主机寻址的器件,他可以是发送器或接收器。
SDA SCL 总线状态
高电平 高电平 空闲(stop之后)
高到低 高电平 START(之后视为忙状态)
低到高 高电平 STOP

上表所示总线起止条件如图所示:
1.jpg-23.7kB

5.2.2米字管

芯片 端口 管脚
U4 P1 2
P2 3
P3 4
P4 5
P5 1
U5 P1 8
P2 9
P3 10
P4 11
P5 12
P6 13
P7 14
U6 P1 16
P2 17
P3 18
P4 7
P5 15

5.2.3流程图

Created with Raphaël 2.1.2Start配置管脚为I2C模式初始化米字管编写拉高拉低电平的函数设置米字管管选信号点亮米字管相应码段End

5.3实现功能

5.4实验代码

5.4.1预设数字码段

  1. static const char tubeDigital[10][2]=
  2. { // SegmLow, SegHigh
  3. { 0x10, 0x3E }, // 0
  4. { 0x00, 0x18 }, // 1
  5. { 0x70, 0x2C }, // 2
  6. { 0x70, 0x26 }, // 3
  7. { 0x60, 0x32 }, // 4
  8. { 0x70, 0x16 }, // 5
  9. { 0x70, 0x1E }, // 6
  10. { 0x00, 0x26 }, // 7
  11. { 0x70, 0x3E }, // 8
  12. { 0x70, 0x36 }, // 9
  13. };

5.4.2中断的配置及初始化

  1. /*******************************************************************
  2. * 函数: I2C_Init()
  3. * 描述: I2C初始化
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void I2C_Init()
  8. {
  9. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  10. /*B2设置为SCL时钟线,B3设置为SDA串行数据线*/
  11. GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
  12. /*设置B的引脚复用功能为SCL和SDA*/
  13. GPIOPinConfigure(GPIO_PB2_I2C0SCL);
  14. GPIOPinConfigure(GPIO_PB3_I2C0SDA);
  15. GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
  16. GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
  17. SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); //使能I2C0模块
  18. /* 设I2C主机模式, 使用系统时钟, 400kbps的快速模式(false普通模式100Kbps)*/
  19. I2CMasterInitExpClk(I2C0_BASE,1000000, true);
  20. I2CMasterEnable(I2C0_BASE); //使能I2C0主机模式
  21. I2CSlaveEnable(I2C0_BASE);//使能I2C从机模式
  22. }

5.4.3米字管芯片初始化

  1. /********************************************************************
  2. * 函数: PCA9557_Init()
  3. * 描述: PCA9557初始化
  4. * 输入值:无
  5. * 返回值:无
  6. ******************************************************************/
  7. void PCA9557_Init()
  8. { uint8_t SendBuff[2] = {PCA9557_REG_CONFIG, 0x00};
  9. //PCA9557_REG_CONFIG(COMMAND BYTE)配置成读写模式
  10. I2C_SendBuff(I2C0_ADDR_TUBE_SEL, SendBuff, 2);
  11. //U21管选 I2C0_ADDR_TUBE_SEL (SLAVE ADDR)
  12. I2C_SendBuff(I2C0_ADDR_TUBE_SEG_LOW, SendBuff, 2);
  13. //U22管选 I2C0_ADDR_TUBE_SEG_LOW(SLAVE ADDR)
  14. I2C_SendBuff(I2C0_ADDR_TUBE_SEG_HIGH, SendBuff, 2);
  15. //U23管选 I2C0_ADDR_TUBE_SEG_HIGH(SLAVE ADDR)
  16. }

5.4.4点亮米字管

  1. /*******************************************************************
  2. * 函数: MZG_run()
  3. * 描述: 点亮米字管为a,b,c,d(在while里的动态显示)
  4. * 输入值:uint8_t a,b,c,d
  5. * 返回值:无
  6. *****************************************************************/
  7. void MGZ_run(){
  8. int t=50;//这个延时时间
  9. I2C_ClearTheTube(); //清屏
  10. I2C_U4TubeSelect(~0x20); //选择数字管1
  11. I2C_U5TubeLowPinControl(tubeDigital[a][0]);//拉低U5的引脚
  12. I2C_U3TubeHighPinControl(tubeDigital[a][1]);//拉高U3引脚
  13. DelayMs(t);
  14. I2C_ClearTheTube(); //清屏
  15. I2C_U4TubeSelect(~0x02); //选择数字管2
  16. I2C_U5TubeLowPinControl(tubeDigital[b][0]);//拉低U5的引脚
  17. I2C_U3TubeHighPinControl(tubeDigital[b][1]);//拉高U3引脚
  18. DelayMs(t);
  19. I2C_ClearTheTube(); //清屏
  20. I2C_U4TubeSelect(~0x04); //选择数字管3
  21. I2C_U5TubeLowPinControl(tubeDigital[c][0]);//拉低U5的引脚
  22. I2C_U3TubeHighPinControl(tubeDigital[c][1]);//拉高U3引脚
  23. DelayMs(t);
  24. I2C_ClearTheTube(); //清屏
  25. I2C_U4TubeSelect(~0x08); //选择数字管4
  26. I2C_U5TubeLowPinControl(tubeDigital[d][0]);//拉低U5的引脚
  27. I2C_U3TubeHighPinControl(tubeDigital[d][1]);//拉高U3引脚
  28. DelayMs(t);
  29. }

5.5遇到的问题和解决办法

5.6实验结论

实验六 ADC和UART

6.1实验目的

  • 学习ADC模块原理和串口通信的原理
  • 学习使用ADC模块转化外设传感器数据变为可调用的数字信息
  • 将信息用UART输出

6.2实验原理

6.2.1ADC

6.2.1.1结构特点
6.2.1.2初始化与配置
6.2.1.3功能描述
序列发生器 采样数 FIFO深度
SS3 1 1
SS2 2 4
SS1 3 4
SS0 8 8

SS处理采样控制和数据采集,所有序列发生器的实现方式相同,但采样数和FIFO深度不同。每个FIFO单元均为一个32位的字,低12位包含的是转换结果

  1. //配置PE3口为ADC单端采样模式,使用采样序列3采样内置温度感应器,处理器信号触发方式。
  2. void main(){
  3. int pui32ADC0Value;
  4. //初始化系统时钟
  5. g_ui32SysClock=SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ|SYSCTL_OSC_MAIN|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480),120000000);
  6. //开启ADC0时钟
  7. SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
  8. //使能温度传感器PE3
  9. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
  10. //将PE3口配置成AD输入模式
  11. GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3);
  12. //使用采样序列3来采样,ADC_TRIGGER_PROCESSOR为设定触发方式为控制器触发,由ADCProcessorTrigger()配合使用。
  13. ADCSequenceConfigure(ADC0_BASE,3,ADC_TRIGGER_PROCESSOR,0);
  14. //配置采样序列3的步骤0,配置模拟通道0(ADC_CTL_CH0)、采样结束产生中断(ADC_CTL_IE),转化结束后告诉ADC逻辑转化结束
  15. ADCSequenceStepConfigure(ADC0_BSE,3,0,ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
  16. //使能采样序列3
  17. ADCSequenceEnable(ADC0_BASE,3);
  18. //开始采样前先清除采样序列3产生的中断
  19. ADCIntClear(ADC0_BASE,3);
  20. while(1){
  21. //触发ADC0SS3。
  22. ADCProcessorTrigger(ADC0_BASE,3);
  23. //等待转换结束
  24. while(!ADCIntStatus(ADC0_BASE,3,false)){}
  25. //清除中断标志
  26. ADCIntClear(ADC0_BASE,3);
  27. //读取ADC0采样序列SS3的转化值,将结果存在pui32ADC0Value
  28. ADCSequenceDataGet(ADC0_BASE,3,pui32ADC0Value);
  29. //延时
  30. SysCtlDelay(g_ui32Sysclock/12);
  31. }
  32. }
  1. #include "inc/hw_types.h"
  2. #include "inc/hw_memmap.h"
  3. #include "driverlib/sysctl.h"
  4. #include "driverlib/pin_map.h"
  5. #include "driverlib/gpio.h"
  6. #include "inc/hw_gpio.h"
  7. #include "driverlib/adc.h"

6.2.2UART

UART(Universal Asynchronous Receiver/Transmitter), 异步串行通信接口,它可以实现数据的并串行转换,相对于同步模式,异步模式不需要一个专门的时钟信号来控制数据的收发,因此发送数据时位与位之间的间隙可以任意改变,但是并不是说不需要时钟信号,而是通过系统时钟或全局备用时钟产生一个可编程的波特时钟来控制发送数据。

  • 接收处理器内部的并行数据,通过串行发送总线UnTX以异步通信的方式发送出去
  • 输入接收总线UnRX上的串行数据,转换为并行数据后返回给处理器处理
  • 数据接收或处理完后,经过T/R缓冲区FIFO,
6.2.2.1发送/接收

标准的异步通信包括起始位,停止位,奇偶校验位。控制逻辑输出串行位流时,最先输出起始位,然后输出若干数据位(最低有效位在前),奇偶校验位和停止位。

接收逻辑单元在检测到有效的起始脉冲后,对接收到的串行位码流进行串-并转换,在接收过程中还要进行溢出错误检测、奇偶校验、帧错误检测、线终止检测、并将这些状态随数据一同写入接收FIFO中。

6.2.2.2波特率的产生

波特率分频系数是由16位整数部分和6位小数部分组成的22位二进制数,由此决定位时间,其中整数由UART波特率分频值整数(UARTIBRD)寄存器加载,小数通过UART波特率分频值小数(UARTFBRD)寄存器加载。波特率分频值(BRD)和系统时钟之间关系如下:

BRD=BRDI+BRDF=UARTSysClk/(ClkDiv*波特率)

式中UARTSysClk是连接到UART的系统时钟,ClkDiv是一个常数,取值为16或8(对应UARTCTL寄存器里第五位HSE=0/1,因此UART模块产生的内部波特率参考时钟频率总为波特率的8或16倍,分别称为)。默认情况下该系统时钟为‘时钟控制’中描述的主系统时钟,6位小数部分(寄存器[UARTFBRD]里[DIVFRAC]位域的值)计算方法如下:

UARTFBRD[DIVFRAC]=integer(BRDF*64+0.5)

即将波特率除数的小数部分乘64,加0.5以抵消舍入误差。需注意的是,梗概波特率除数之后,必须写一次(高字节)UARTLCRH寄存器,更改内容才会生效。

6.2.2.3初始化和配置

uart有8个模块,其中uart0是我们要用到的,它有调制解调器的功能(调制解调器流控制和调制解调器状态)//UART0使用PA0,PA1两个引脚,因此要使能GPIOA模块。

  1. //UART0使用PA0,PA1两个引脚,首先使能GPIOA模块
  2. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  3. //GPIO管脚复用,所以要对PA0,PA1两个引脚功能进行选择,这里将他们选择为执行UART0模块功能
  4. GPIOPinConfigure(GPIO_PA0_U0RX);//PA0用于接收数据
  5. GPIOPinConfigure(GPIO_PA1_U0TX);//PA1用于发送数据
  6. //将PA0,PA1作为UART功能使用前进行配置
  7. GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);
  8. UARTStdioConfig(0,115200,g_ui32SysClock);
  1. //sysctl.h
  2. //使能外设模块基址
  3. void SysCtlPeripheralEnable(uint32_t ui32Peripheral);
  4. //函数的定义和ui8Pins在gpio.h
  5. //ui32PinConfig在pin_map.h,ui32Port在hw_mammap.h
  6. //GPIOPinConfigure()一般和GPIOPinType...()一起使用来配置引脚。
  7. void GPIOPinConfigure(uint32_t ui32PinConfig);
  8. void GPIOPinTypeUART(uint32_t ui32Port, uint8_t ui8Pins);

6.3实现功能

6.4实验代码

6.4.1ADC和滚轮的初始化

  1. /*******************************************************************
  2. * 函数: ADC_Init()
  3. * 描述: 初始化ADC0序列3和滚轮
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void ADC_Init()
  8. {
  9. // 初始化ADC0/PD7 AIN4 共20通道最大AIN19 分辨率为12bit 最大值4096
  10. SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //可选两个模块 ADC0和ADC1
  11. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
  12. GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7);
  13. ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
  14. ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_END | ADC_CTL_IE);
  15. ADCSequenceEnable(ADC0_BASE, 3);
  16. ADC0_HandlerFlag = false; //中断未发生
  17. }

6.4.2数据采集并用串口输出

  1. /*******************************************************************
  2. * 函数: ADC_work()
  3. * 描述: 数据采集,转化并用串口输出
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void ADC_work()
  8. {
  9. uint32_t ADC0_SS3v;
  10. uint32_t ADC0_result;
  11. ADCProcessorTrigger(ADC0_BASE, 3);
  12. while(!ADCIntStatus(ADC0_BASE, 3, false)) ;
  13. ADCSequenceDataGet(ADC0_BASE, 3, &ADC0_SS3v);
  14. ADC0_result=(ADC0_SS3v * 3.3 *1000)/4096;
  15. UARTprintf("V:%04d \n ", ADC0_result);
  16. }

6.5实验结论

实验七 三轴加速度传感器

7.1实验目的

  • 依旧是通信,这次是用控制板子上的三轴加速度传感器ADXL345。
  • 这次不用串口,而是通过得到的数据识别板子的姿态。因为ADXL345本身就会把得到的数据以数字形式存放在寄存器里,所以直接读取即可,不需要用到模数转换ADC模块。
  • 学会单步观察参数调节程序。
  • 需要用到模块:ADXL345,

7.2实验原理

引脚编号 引脚名称 描述
1 Vdd 数字接口电源电压
2 GND 该引脚必须接地
3 RESERVED 保留。该引脚必须连接到VC或者保持断开
4 GND 该引脚必须接地
5 GND 该引脚必须接地
6 VC 电源电压
7 CS 片选
8 INT1 中断1输出
9 INT2 中断2输出
10 NC 内部不连接
11 RESERVED 保留。该引脚必须接地或保持断开
12 SDO/ALT ADDRESS 串行数据输出(SPI4线)备用I2C地址选择
13 SDA/SDI/SDIO 串行数据(I2C)串行数据输入(SPI4)/串行数据输入和输出(SPI3)
14 SCL/SCLK 串行通信时钟,SCL为I2C时钟SCLK为SPI时钟

7.3实现功能

7.4实验代码

  1. /*******************************************************************
  2. * 函数: ADXL345_run()
  3. * 描述: 读取处理加速度器寄存器数据,识别板子十种不同姿态
  4. * 输入值:无
  5. * 返回值:无
  6. *****************************************************************/
  7. void ADXL345_run(){
  8. ADXL345_Read(DataXYZ); //连续6次分别读取0x32-0x37中的数据。
  9. ADXL345_DataProcess(DataXYZ,DataMg); //对数据进行处理
  10. if((DataMg[0] == OneG)&&(DataMg[3]== Positive))
  11. { ledclose(); LED_ON(4); }
  12. else if((DataMg[0] == OneG)&&(DataMg[3]== Negative))
  13. { ledclose();LED_ON(0); }
  14. else if((DataMg[1] == OneG)&&(DataMg[4]== Negative))
  15. { ledclose(); LED_ON(6); }
  16. else if((DataMg[1] == OneG)&&(DataMg[4]== Positive))
  17. { ledclose(); LED_ON(2); }
  18. else if((DataMg[2] == OneG)&&(DataMg[5]== Negative))
  19. { ledclose(); }
  20. //*************************************************************8
  21. else if((DataMg[3]== Negative)&&(DataMg[4]== Negative))
  22. { ledclose(); LED_ON(7); }
  23. else if((DataMg[3]== Negative)&&(DataMg[4]== Positive))
  24. { ledclose(); LED_ON(1); }
  25. else if((DataMg[3]== Positive)&&(DataMg[4]== Positive))
  26. { ledclose(); LED_ON(3); }
  27. else if((DataMg[3]== Positive)&&(DataMg[4]== Negative))
  28. { ledclose(); LED_ON(5); }
  29. }

7.5实验结论

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注