ARM串口实验,ADC实验,I2C实验

来源:互联网 发布:dota2 mac版分辨率 编辑:程序博客网 时间:2024/05/22 00:12

1】UART实验

实验目的:通过串口进行收发数据

 

一、看原理图

发现UART接在CPU的GPA1_0和GPA1_1引脚

二、看芯片手册

GPA1CON:

GPA1CON[1]  [7:4]: 0x2 = UART_2_TXD     //UART的发送数据功能

GPA1CON[0]  [3:0]: 0x2 = UART_2_RXD     //UART的接收数据的功能

UART所支持的通信协议:

1个起始位

5-8个数据位

0/1奇偶校验位

1-2个停止位

可编程的波特率

 

我们常用的协议:8N1

1个起始位和1个停止位     8个数据位    没有奇偶校验位         115200

 

ULCONn:

0x3      //选择8N1的协议

 

UCONn

Transmit Mode [3:2]: 01 = Interrupt request or polling mode   //我们用轮询模式(polling)

Receive Mode  [1:0]: 01 = Interrupt request or polling mode

 

UTRSTATn

Transmit buffer empty [1]: 0 = Buffer is not empty     //等待

    1 = Buffer is empty         //可以发送

 

Receive buffer data ready [0]: 0 = Buffer is empty     //等待

1 = Buffer has a received data //可以读

 

UTXHn

UTXHn  [7:0]  RWX  Transmits data for UARTn       //发送数据

URXHn

URXHn  [7:0]  R  Receives data for UARTn          //接收数据

 

UBRDIVn

UBRDIVn  [15:0]:              53

UFRACVALn

UFRACVALn  [3:0]:             5

 

 

For example, if the Baud rate is 115200 bps and SCLK_UART is 40 MHz, UBRDIVn and UFRACVALn are:

DIV_VAL = (40000000/(115200*16))-1

= 21.7 – 1

= 20.7

UBRDIVn = 20 (integer part of DIV_VAL)

UFRACVALn/16 = 0.7

 

 

DIV_VAL = (100000000/(115200*16))-1

= 53.3

UBRDIVn = 53  (integer part of DIV_VAL)

UFRACVALn/16 = 0.3

UFRACVALn = 5

 

 

 

1.2】RTC

RTCCON

CTLEN  [0]: 0 = Disables RTC control

     1 = Enables RTC control

 

 

BCDSEC

BCDSEC = 0x30

 

 

【2】ADC

实验目的:测量电位器两段的电压,进行转化

 

ADCCON

RES  [16]:1 = 12bit A/D conversion   //12位的转化精度

ECFLG  [15]: 0 = A/D conversion in process             //判断AD转化是否结束的标记

      1 = End of A/D conversion

PRSCEN  [14]: A/D converter prescaler enable  1 = Enable

PRSCVL  [13:6]:0xff

STANDBY  [2]: 0 = Normal operation mode

READ_ START [1]:  A/D conversion start by read          //读一次就开始转化一次

0 = Disables start by read operation

1 = Enables start by read operation

ENABLE_ST ART [0]:1 = A/D conversion starts and this bit is automatically cleared after the start-up.

//使能一次,ADC就开始转化一次

 

ADCDAT

DATA [11:0]  R ADC conversion data value Data value: 0x0 ~ 0xFFF

 

ADCMUX

SEL_MUX  [3:0] : 0011 = AIN 3


I2C

1. 概念,IIC是由PHILIPS公司推出的两线式串行总线,通过串行数据线(SDA)和串行时钟线(SCL)在连接到总线上的设备间进行

   传递消息,每一个设备都有自己唯一的地址识别

2. 看原理图,找到从机设备(三轴加速度传感器)所接的IIC引脚 -- I2C_SCL5 I2C_SDA5

   配置相关引脚为IIC功能  -- XspiMISO0/I2C_5_SDA/GPB_2   XspiMOSI0/I2C_5_SCL/GPB_3

   1. GPBCON

      GPBCON[2]   [11:8]:0x3 = I2C_5_SDA

      GPBCON[3]  [15:12]:0x3 = I2C_5_SCL

   2. GPBPUD

      GPBPUD[n] [2n + 1:2n]:0x0 = Disables Pull-up/Pull-down

   

3. 看芯片手册上的IIC概述

   1. 当IIC被闲置的时候,SDA和SCL都处于高电平,在SCL处于高电平的时候,SDA的一个下降沿表示一个start信号

                                                                      SDA的一个上升沿表示一个stop信号

   2. 我们的start和stop信号都是有主机设备产生的

   3. 主机发送start信号后接着通过SDA发送一个7bits的地址,这个地址决定主机要通信的从机设备,第八位决定主机是要读

      从机设备还是写从机设备

      SDA发送的数据只能是八位八位的,在接收到一个字节后会立马发出一个响应信号(ACK)

      主机通过判断中断挂起位来判断是否接受到数据或者ACK应答信号

 

   4. IIC的四种操作模式

      主机发送、主机接收、从机发送、从机接收

   5. 分析时序图

      

   6. 寄存器  - 看原理图发现我们的三轴加速度传感器接I2C_SCL5

      1. I2CCON5

         Acknowledge generation     [7]: 1 = Enables

                                         In Tx mode, the I2CSDA is idle in the ACK time.

                                         In Rx mode, the I2CSDA is low in the ACK time

         注意: ACK generation is disabled before Reading the last data to generate the STOP condition in Rx mode.

         Tx clock source selection  [6]: 0 = I2CCLK = fPCLK/16

                                         1 = I2CCLK = fPCLK/512

         Tx/Rx Interrupt  (5)       [5]: 1 = Enables

         Interrupt pending flag     [4]: 0 = 1) No interrupt is pending (If Read).     //没有收到ACK

                                             2) Clears pending condition and resumes the operation (if Write).

                                         1 = 1) Interrupt is pending (If Read)         //接收到ACK

                                             2) N/A (If Write)

         Transmit clock value (4) [3:0]: Tx clock = I2CCLK/(I2CCON[3:0] + 1)

      2. I2CSTAT5

         Mode selection  [7:6]: 00 = Slave receive mode

                                01 = Slave transmit mode

                                10 = Master receive mode

                                11 = Master transmit mode

         Busy signal status/START STOP condition [5]: 0 = (Read) Not busy (If Read)

                                                          (write) STOP signal generation

                                                      1 = (Read) Busy (If Read)

                                                          (write) START signal generation.

                                                      Transfers the data in I2CDS automatically just after the start signal.

         Serial output    [4]: 1 = Enables Rx/Tx

         Last-received bit status flag [0]:1 = Last-received bit is set to 1 (does not receive ACK).

      3. I2CADD5                               //用来读从机地址的

         Slave address  [7:0]: Slave address: [7:1]

      4. I2CDS5

         Data shift     [7:0]: 8-bit data shift register for I2C-bus Tx/Rx operation

 

4. 看MPU6050的数据手册(Datasheet)

   1. The slave address of the MPU-60X0 is b110100X which is 7 bits long. The LSB bit of the 7 bit address is

      determined by the logic level on pin AD0

      经查看三轴加速度的原理图发现AD0为0,所以从机地址是0x68  ==》  slave_addr = 0x68

   2. To read the internal MPU-60X0 registers, the master sends a start condition, followed by the IIC address and

      a write bit, and then the register address that is going to be read

      当要对MPU6050内部的寄存器进行操作时,在发送完IIC从机地址收到ACk后还要接着发送6050内部寄存器地址

   2. 分析主发从(MPU6050)收的时序

 

5. 查看MPU6050的寄存器手册(Register Map)  寄存器都是8位的

   SMPLRT_DIV      0x19 //陀螺仪采样率,典型值:0x07(125Hz)                                 

   CONFIG          0x1A //低通滤波频率,典型值:0x06(5Hz)                                   

   GYRO_CONFIG     0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)             

   ACCEL_CONFIG    0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x18(不自检,2G,5Hz)                                                                                                                                          

   GYRO_ZOUT_H     0x47 //获取MPU6050-Z轴角速度高字节                                                                   

   GYRO_ZOUT_L     0x48 //获取MPU6050-Z轴角速度低字节                                                                   

   PWR_MGMT_1      0x6B //电源管理,典型值:0x00(正常启用)  用来设置6050内部时钟                                

 

6. 写程序

   iic_init

   /* 1. 初始化GPIO引脚为IIC相关功能 */

   GPBCON = GPBCON & (~(0xf<<8))  | (0x3<<8);      //配置GPB_2引脚为IIC_SDA

   GPBCON = GPBCON & (~(0xf<<12)) | (0x3<<12);     //配置GPB_3引脚为IIC_SCL

   

   /* 2. 设置IIC的工作时钟,使能IIC中断,使能ACK */

   I2CCON5 |= (0x7<<5);

   

   /* 3. 使能IIC串口输出 */

   I2CSTAT5 |= (1<<4);

 

   /*********************************************************************************************************/

 

   iic_write  -- 参数:addr_slave(从机地址)   addr_slave_reg(从机寄存器地址)  data

   /* 1. 发送start信号 */

   I2CSTAT5 |= (1<<5);

   

   /* 2. 设置主发模式 */

   I2CSTAT5 |= (3<<6);

   

   /* 3. 发送IIC从机设备地址 */

   I2CDS5 = (0x68<<1);

   while(!(I2CCON5 & (1<<4)));     //等待,直到中断被挂起(收到ACK)

   

   /* 4. 发送从设备内部寄存器地址,发送后先清中断挂起(从新开始发送),然后再等待中断被挂起(收到ACK) */

   I2CDS5 = addr_slave_reg;

   I2CCON5 &= ~(1<<4);             //清中断挂起位

   while(!(I2CCON5 & (1<<4)));     //等待,直到中断被挂起(收到ACK)

   

   /* 5. 发送数据,发送前先等待中断被挂起(收到ACK),然后清中断挂起,最后再发送 */

   I2CDS5 = data;

   I2CCON5 &= ~(1<<4);

   while(!(I2CCON5 & (1<<4)));

   

   /* 6. 发送stop信号,禁止接受ACK */

   I2CSTAT5 = 0xd0;

   

   /* 请中断挂起 */

   I2CCON5 &= ~(1<<4);

   

   delay_ms(10);

   

   /*********************************************************************************************************/

   

   iic_read  -- 参数:addr_slave(从机地址)   addr_slave_reg(从机寄存器地址)

   /* 1. 发送start信号 */

   I2CSTAT5 |= (1<<5)|(1<<4);

   

   /* 2. 设置主发模式 */

   I2CSTAT5 |= (3<<6);

   

   /* 3. 发送IIC从机设备地址+写0 */

   I2CDS5 = (0x68<<1);

   while(!(I2CCON5 & (1<<4)));     //等待,直到中断被挂起(收到ACK)

   

   /* 4. 发送从设备内部寄存器地址,发送后先清中断挂起(从新开始发送),然后再等待中断被挂起(收到ACK) */

   I2CDS5 = addr_slave_reg;

   I2CCON5 &= ~(1<<4);             //清中断挂起位

   while(!(I2CCON5 & (1<<4)));     //等待,直到中断被挂起(收到ACK)

   

   /* 5. 清中断,发stop信号 */

   I2CCON5 &= ~(1<<4);

   I2CSTAT5 = 0xd0;

   

   /* 6. 设置主机接收模式 */

   I2CSTAT5 = I2CSTAT5& (~(3<<6)) | (2<<6);

   

   /* 7. 发送start信号,发从机地址+读1位 */

   I2CSTAT5 |= (1<<5);

   I2CDS5 = (0x68<<1) | 0x1;

   while(!(I2CCON5 & (1<<4)));

   

   /* 5. 发送数据,发送前先等待中断被挂起(收到ACK),然后清中断挂起,最后再发送 */

   I2CDS5 = data;

   I2CCON5 &= ~(1<<4);

   while(!(I2CCON5 & (1<<4)));

   

   /* 6. 发送stop信号 */

   I2CSTAT5 = 0xd0;

   

   /* 清中断挂起位 */

   I2CCON5 &= ~(1<<4);

   

   delay_ms(10);

   

   /*********************************************************************************************************/

   

   init_mpu6050

   iic_write(SlaveAddress, PWR_MGMT_1, 0x00);   //设置使用内部时钟8M

   iic_write(SlaveAddress, SMPLRT_DIV, 0x07);   //设置陀螺仪采样率

   iic_write(SlaveAddress, CONFIG, 0x06);   //设置数字低通滤波器

   iic_write(SlaveAddress, GYRO_CONFIG, 0x18);   //设置陀螺仪量程+-2000度/s

   iic_write(SlaveAddress, ACCEL_CONFIG, 0x0);   //设置加速度量程+-2g

 

   最后一步,在main中读Z轴的加速度

   zvalue_h = iic_read(SlaveAddress, GYRO_ZOUT_H); //获取MPU6050-Z轴角速度高字节

   zvalue_l = iic_read(SlaveAddress, GYRO_ZOUT_L); //获取MPU6050-Z轴角速度低字节

   zvalue  =  (zvalue_h<<8)|zvalue_l; //获取MPU6050-Z轴角速度

0 0
原创粉丝点击