赞
踩
1、6ULL的PWM是16位计数器,
2、有4个16位的FIFO。
3、一个12位的分频器
4、正点原子LCD屏幕的背光IO连接到了GPIO1_IO08上。
GPIO1_IO08可以复用位PWM1_OUT信号。
PWM计数器从0X0000开始计数,当计数器的值等于PWMPR+1的时候定时器就会重新开始下一个周期的运行,因此PWMPR寄存器控制着PWM频率。
FIFO保存着采样值,当我们向PWMSAR寄存器写采样值的时候会写道FIFO里面,内每当读取一次PWMSAR寄存器,FIFO里面的数据都会减一,或者每产生一个PWM信号,FIFO的数据也会减一。直到FIFO为空,那么就无法再产生PWM信号。FIFO为空的时候会产生中断,我们可以在中断中向FIFO写入采样数据,也就是向PWMSAR写数据。
PWMCR寄存器,bit0是PWM使能信号,bit2:1设置为0,每个周期使用FIFO里面的一个数据。Bit15:4,PWM分频设置,可以设置04095,对应14096分频。Bit17:16设置PWM时钟源,设置为1,表示使用ipg_clk=66MHz。bit19:18,设置为0。Bit27:26,设置为01,表示当FIFO里面空余位置大于2的时候FIFO为空。
PWMIR寄存器,bit0设置为1,开启FIFO空中断。
//bsp_bmp280.h #ifndef _BSP_BMP280_H #define _BSP_BMP280_H #include "imx6ul.h" #include "bsp_gpio.h" /* 宏定义 */ #define BMP280_CSN(n) (n ? gpio_pinwrite(GPIO1, 20, 1) : gpio_pinwrite(GPIO1, 20, 0)) //SPI片选信号 #define BMP280_ID_VALUE 0X58 /* BMP280 ID值 */ #define BMP280_RESET_VALUE 0XB6 /* BMP280复位值 */ /* BMP280寄存器宏定义 */ #define BMP280_TEMPXLSB_REG 0XFC /* 温度值的bit[3:0]寄存器 */ #define BMP280_TEMPLSB_REG 0XFB /* 温度值的bit[11:4]寄存器 */ #define BMP280_TEMPMSB_REG 0XFA /* 温度值的bit[19:12]寄存器 */ #define BMP280_PRESXLSB_REG 0XF9 /* 压力值的bit[3:0]寄存器 */ #define BMP280_PRESLSB_REG 0XF8 /* 压力值的bit[11:4]寄存器 */ #define BMP280_PRESMSB_REG 0XF7 /* 压力值的bit[19:12]寄存器 */ #define BMP280_CONFIG_REG 0XF5 /* 配置寄存器 */ #define BMP280_CTRLMEAS_REG 0XF4 /* 测量配置寄存器 */ #define BMP280_STATUS_REG 0XF3 /* 状态寄存器 */ #define BMP280_RESET_REG 0XE0 /* 复位寄存器 */ #define BMP280_ID_REG 0XD0 /* ID寄存器 */ #define BMP280_TRIMPARAM_FRG 0X88 /* 参数组寄存器首地址 */ #define BMP280_TRIMPARAM_LEN 24 /* 参数组寄存器长度 */ #define BMP280_INVALID_DATA 0 /* 无效的数据 */ /* * BMP280 参数结构体 */ struct bmp280_calib_param { unsigned short dig_T1; /* T1参数 */ short dig_T2; /* T2参数 */ short dig_T3; /* T3参数 */ unsigned short dig_P1; /* P1参数 */ short dig_P2; /* P2参数 */ short dig_P3; /* P3参数 */ short dig_P4; /* P4参数 */ short dig_P5; /* P5参数 */ short dig_P6; /* P6参数 */ short dig_P7; /* P7参数 */ short dig_P8; /* P8参数 */ short dig_P9; /* P9参数 */ signed int t_fine; /* t_fine参数*/ }; /* * BMP280结构体 */ struct bmp280_dev_struc { struct bmp280_calib_param calib_param; signed int uncomp_temp; /* 原始的温度值 */ signed int uncomp_pres; /* 原始的压力值 */ signed int actual_temp; /* 真实的温度值 */ signed int actual_pres; /* 真实的压力值 */ }; extern struct bmp280_dev_struc bmp280_dev; /* 函数声明 */ unsigned char bmp280_init(void); unsigned char bmp280_read_reg(unsigned char reg); void bmp280_read_len(unsigned char reg, unsigned char *buf, unsigned char len); void bmp280_write_reg(unsigned char reg, unsigned char value); void bmp280_get_calibparam(void); signed int bmp280_get_uncomptemp(void); signed int bmp280_get_uncomppres(void); signed int bmp280_get_actualtemp(signed int uncomptemp); unsigned int bmp280_get_actualpres(s32 uncomppres); #endif
//bsp_bmp280.c #include "bsp_bmp280.h" #include "bsp_delay.h" #include "bsp_spi.h" #include "stdio.h" /* BMP280属性结构体 */ struct bmp280_dev_struc bmp280_dev; //初始化BMP280 //返回0 初始化成功,其他值 初始化失败 unsigned char bmp280_init(void) { unsigned char regvalue; gpio_pin_config_t cs_config; /* 1、初始化SPI */ spi3_init(); /* 2、初始化片选引脚 */ IOMUXC_SetPinMux(IOMUXC_UART2_TX_DATA_GPIO1_IO20, 0); IOMUXC_SetPinConfig(IOMUXC_UART2_TX_DATA_GPIO1_IO20, 0X10B0); cs_config.direction = kGPIO_DigitalOutput; cs_config.outputLogic = 1; gpio_init(GPIO1, 20, &cs_config); /* 4、配置BMP280 */ regvalue = bmp280_read_reg(BMP280_ID_REG);/* 读取ID */ if(regvalue == BMP280_ID_VALUE) { printf("bmp280 id = %#X\r\n", regvalue); } else { return 1; } bmp280_write_reg(BMP280_RESET_REG, BMP280_RESET_VALUE); /* 复位BMP280 */ bmp280_write_reg(BMP280_CTRLMEAS_REG, 0); /* 进入睡眠模式才可以写控制寄存器 */ /* 设置BMP280使用Ultra high resolution模式,即: * osrs_p为X16,osrs_t为X2,IIR Filter为16 */ /* *配置BMP280控制寄存器CONFIG_REG *bit[7:5] : 000 normal模式下的T_standby,0.5ms *bit[4:2] : 111 IIR滤波器的时间常量 X16 *bit[0] : 0 禁止3线SPI模式 */ bmp280_write_reg(BMP280_CONFIG_REG, 0x1C); /* *配置BMP280测量寄存器CTRLMEAS_REG *bit[7:5] : 010 温度采样率x2 17bit/0.0025°C *bit[4:2] : 111 压力采样率x16 20bit/0.16Pa *bit[1:0] : 11 normal模式 */ bmp280_write_reg(BMP280_CTRLMEAS_REG, 0x5F); bmp280_get_calibparam(); /* 计算参数 */ return 0; } //计算BMP280的计算参数 void bmp280_get_calibparam(void) { unsigned char param_buf[BMP280_TRIMPARAM_LEN]; /* 读取BMP280的参数 */ bmp280_read_len(BMP280_TRIMPARAM_FRG, param_buf, BMP280_TRIMPARAM_LEN); /* 计算参数 */ bmp280_dev.calib_param.dig_T1 = (u16)((((u16)((u8)param_buf[1])) << 8) | param_buf[0]); bmp280_dev.calib_param.dig_T2 = (s16)((((s16)((s8)param_buf[3])) << 8) | param_buf[2]); bmp280_dev.calib_param.dig_T3 = (s16)((((s16)((s8)param_buf[5])) << 8) | param_buf[4]); bmp280_dev.calib_param.dig_P1 = (u16)((((u16)((u8)param_buf[7])) << 8) | param_buf[6]); bmp280_dev.calib_param.dig_P2 = (s16)((((s16)((s8)param_buf[9])) << 8) | param_buf[8]); bmp280_dev.calib_param.dig_P3 = (s16)((((s16)((s8)param_buf[11])) << 8) | param_buf[10]); bmp280_dev.calib_param.dig_P4 = (s16)((((s16)((s8)param_buf[13])) << 8) | param_buf[12]); bmp280_dev.calib_param.dig_P5 = (s16)((((s16)((s8)param_buf[15])) << 8) | param_buf[14]); bmp280_dev.calib_param.dig_P6 = (s16)((((s16)((s8)param_buf[17])) << 8) | param_buf[16]); bmp280_dev.calib_param.dig_P7 = (s16)((((s16)((s8)param_buf[19])) << 8) | param_buf[18]); bmp280_dev.calib_param.dig_P8 = (s16)((((s16)((s8)param_buf[21])) << 8) | param_buf[20]); bmp280_dev.calib_param.dig_P9 = (s16)((((s16)((s8)param_buf[23])) << 8) | param_buf[22]); } //读取BMP280寄存器值 //reg : 要读取的寄存器地址 //返回读取到的寄存器值 unsigned char bmp280_read_reg(unsigned char reg) { unsigned char reg_val; /* BMP280在使用SPI接口的时候寄存器地址 * 只有低7位有效,寄存器地址最高位是读/写标志位 * 读的时候要为1,写的时候要为0。 */ reg |= 0x80; BMP280_CSN(0); /* 使能SPI传输 */ spi3ch0_readwrite_byte(reg); /* 发送寄存器地址 */ reg_val = spi3ch0_readwrite_byte(0XFF); /* 读取寄存器的值 */ BMP280_CSN(1); /* 禁止SPI传输 */ return(reg_val); /* 返回读取到的寄存器值 */ } //读取BMP280连续多个寄存器 //reg : 要读取的寄存器地址 //返回读取到的寄存器值 void bmp280_read_len(unsigned char reg, unsigned char *buf, unsigned char len) { unsigned char i; /* BMP280在使用SPI接口的时候寄存器地址 * 只有低7位有效,寄存器地址最高位是读/写标志位 * 读的时候要为1,写的时候要为0。 */ reg |= 0x80; BMP280_CSN(0); /* 使能SPI传输 */ spi3ch0_readwrite_byte(reg); /* 发送寄存器地址 */ for(i = 0; i < len; i++) /* 顺序读取寄存器的值 */ { buf[i]=spi3ch0_readwrite_byte(0XFF); } BMP280_CSN(1); /* 禁止SPI传输 */ } //写BMP280指定寄存器 //reg : 要读取的寄存器地址 //value: 要写入的值 void bmp280_write_reg(unsigned char reg, unsigned char value) { /* BMP280在使用SPI接口的时候寄存器地址 * 只有低7位有效,寄存器地址最高位是读/写标志位 * 读的时候要为1,写的时候要为0。 */ reg &= ~0x80; BMP280_CSN(0); /* 使能SPI传输 */ spi3ch0_readwrite_byte(reg); /* 发送寄存器地址 */ spi3ch0_readwrite_byte(value); /* 发送要写入的值 */ BMP280_CSN(1); /* 禁止SPI传输 */ } //获取BMP280原始的温度数据值 //返回原始的温度数据值 signed int bmp280_get_uncomptemp(void) { unsigned char temp_value[3]; signed int uncomp_temp = 0; bmp280_read_len(BMP280_TEMPMSB_REG, temp_value, 3); uncomp_temp = (s32)((((u32)(temp_value[0])) << 12) | (((u32)(temp_value[1])) << 4) | ((u32)temp_value[2] >> 4)); return uncomp_temp; } //获取BMP280原始的压力数据值 //返回原始的温度数据值 signed int bmp280_get_uncomppres(void) { unsigned char pres_value[3]; signed int uncomp_pres = 0; bmp280_read_len(BMP280_PRESMSB_REG, pres_value, 3); uncomp_pres = (s32)((((u32)(pres_value[0])) << 12) | (((u32)(pres_value[1])) << 4) | ((u32)pres_value[2] >> 4)); return uncomp_pres; } //从BMP280的原始温度数据值计算出真实的温度数据值 //uncomptemp : 原始的温度数据值 //返回得到的真实的数据值,这里将温度值扩大了100倍,比如5123 = 51.23°C。 signed int bmp280_get_actualtemp(signed int uncomptemp) { s32 v_x1_u32r = 0, v_x2_u32r = 0; s32 temperature = 0; /* 计算温度值,X1 */ v_x1_u32r = ((((uncomptemp >> 3) - ((s32)bmp280_dev.calib_param.dig_T1 << 1))) * ((s32)bmp280_dev.calib_param.dig_T2)) >> 11; /* 计算温度值,X2 */ v_x2_u32r = (((((uncomptemp >> 4)- ((s32)bmp280_dev.calib_param.dig_T1)) * ((uncomptemp >> 4) - ((s32)bmp280_dev.calib_param.dig_T1))) >> 12) * ((s32)bmp280_dev.calib_param.dig_T3)) >> 14; /* 计算t_fine */ bmp280_dev.calib_param.t_fine = v_x1_u32r + v_x2_u32r; /* 计算真实的温度值 */ temperature = (bmp280_dev.calib_param.t_fine * 5 + 128) >> 8; return temperature; } //从BMP280的原始气压数据值计算出真实的气压数据值 //uncomppres : 原始的气压数据值 //返回得到的真实的气压数据值,比如23658就是: * 23658Pa = 236.58hPa = 236.58 milllibar。 */ unsigned int bmp280_get_actualpres(s32 uncomppres) { s32 v_x1_u32r = 0; s32 v_x2_u32r = 0; u32 v_pressure_u32 = 0; /* 计算X1 */ v_x1_u32r = (((s32)bmp280_dev.calib_param.t_fine) >> 1) - (s32)64000; /* 计算X2*/ v_x2_u32r = (((v_x1_u32r >> 2) * (v_x1_u32r >> 2)) >> 11) * ((s32)bmp280_dev.calib_param.dig_P6); v_x2_u32r = v_x2_u32r + ((v_x1_u32r * ((s32)bmp280_dev.calib_param.dig_P5)) << 1); v_x2_u32r = (v_x2_u32r >> 2) + (((s32)bmp280_dev.calib_param.dig_P4) << 16); /* 计算X1*/ v_x1_u32r = (((bmp280_dev.calib_param.dig_P3 * (((v_x1_u32r >> 2) * (v_x1_u32r >> 2)) >> 13)) >> 3) + ((((s32)bmp280_dev.calib_param.dig_P2) * v_x1_u32r) >> 1)) >> 18; v_x1_u32r = ((((32768 + v_x1_u32r)) * ((s32)bmp280_dev.calib_param.dig_P1)) >> 15); /* 计算气压值 */ v_pressure_u32 = (((u32)(((s32)1048576) - uncomppres) - (v_x2_u32r >> 12))) * 3125; /* 检查溢出 */ if (v_pressure_u32 < 0x80000000) { if (v_x1_u32r != 0) v_pressure_u32 = (v_pressure_u32 << 1) / ((u32)v_x1_u32r); else return BMP280_INVALID_DATA; } else { if (v_x1_u32r != 0) v_pressure_u32 = (v_pressure_u32 / (u32)v_x1_u32r) * 2; else return BMP280_INVALID_DATA; } /* 计算X1 */ v_x1_u32r = (((s32)bmp280_dev.calib_param.dig_P9) * ((s32)(((v_pressure_u32 >> 3) * (v_pressure_u32 >> 3)) >> 13))) >> 12; /* 计算X2*/ v_x2_u32r = (((s32)(v_pressure_u32 >> 2)) * ((s32)bmp280_dev.calib_param.dig_P8)) >> 13; /* 计算真实的气压值*/ v_pressure_u32 = (u32)((s32)v_pressure_u32 + ((v_x1_u32r + v_x2_u32r + bmp280_dev.calib_param.dig_P7) >> 4)); return v_pressure_u32; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。