|
距离第一次测试,已经很久了,这次带来的是使用SPI读取DS18B20的温度
我们知道ds18b20需要很严格的时序,一般用纯软件的做法,当然效果不是很好,也有用串口的。我支持利用SPI,好处是,读取时不需要关中断。7500带有两个SPI口,支持DMA,FIFO。
因为这个芯片的DMA我不是很熟悉,所以就用了FIFO,为了保证连续发送,所以这个实现需要一个250us秒的定时器,当然,如果你循环周期永远不会大于380,那么在主循环中调用就可以。
直接上代码吧,写起来发现很费劲。
- #include "spidrv.h"
- #include "W7500x.h"
- /* < SSP_StructInit default values
- SSP_InitStructure.SSP_SerialClockRate = 0x00;
- SSP_InitStructure.SSP_FrameFormat = SSP_FrameFormat_MO;
- SSP_InitStructure.SSP_CPHA = SSP_CPHA_1Edge;
- SSP_InitStructure.SSP_CPOL = SSP_CPOL_Low;
- SSP_InitStructure.SSP_DataSize = SSP_DataSize_8b;
- SSP_InitStructure.SSP_SOD = SSP_SOD_RESET;
- SSP_InitStructure.SSP_Mode = SSP_Mode_Master;
- SSP_InitStructure.SSP_NSS = SSP_NSS_Hard;
- SSP_InitStructure.SSP_LBM = SSP_LBM_RESET;
- SSP_InitStructure.SSP_SSE = SSP_SSE_SET;
- SSP_InitStructure.SSP_BaudRatePrescaler = SSP_BaudRatePrescaler_2;
- */
- static u32t _fsm = 0;
- static struct timer _timer;
- static SSP_InitTypeDef SSP1_InitStructure;
- void spi_init(void) {
- _fsm = 0;
- /* SSP0 Init -- SSP Master */
- //SSP_StructInit(&SSP0_InitStructure);
- //SSP0_InitStructure.SSP_FrameFormat = SSP_FrameFormat_MO; // Motorora SPI mode
- //SSP0_InitStructure.SSP_DataSize = SSP_DataSize_16b;
- //SSP_Init(SSP0,&SSP0_InitStructure);
- /* SSP1 Init -- SSP Slave */
- SSP_StructInit(&SSP1_InitStructure);
- SSP1_InitStructure.SSP_DataSize = SSP_DataSize_16b;
- SSP1_InitStructure.SSP_BaudRatePrescaler = SSP_BaudRatePrescaler_254;// SSP_BaudRatePrescaler_254;
- SSP1_InitStructure.SSP_Mode = SSP_Mode_Master;
- SSP1_InitStructure.SSP_CPOL = SSP_CPOL_Low;//SSP_CPOL_High;
-
- SSP1_InitStructure.SSP_FrameFormat = SSP_FrameFormat_MO;
- SSP1_InitStructure.SSP_CPHA = SSP_CPHA_2Edge;
-
- SSP_Init(SSP0,&SSP1_InitStructure);
- //SSP0->DMACR= 0x03;
- //bsp_set_spi1_speed(SPI_SPEED_256);
- //*(u32t *)(0x41003020) = 0x32;
-
- *(u32t *)(0x4100301c) = 0x32;
- }
- #define ff1 0xffff
- #define ff2 ff1, ff1
- #define ff3 ff1, ff2
- #define ff4 ff1, ff3
- #define ff5 ff1, ff4
- #define ff6 ff1, ff5
- #define ff7 ff1, ff6
- #define ff8 ff1, ff7
- #define ff9 ff1, ff8
- #define ff10 ff1, ff9
- #define zz1 0x0
- #define zz2 zz1, zz1
- #define zz3 zz1, zz2
- #define zz4 zz1, zz3
- #define zz5 zz1, zz4
- #define zz6 zz1, zz5
- #define zz7 zz1, zz6
- #define zz8 zz1, zz7
- #define zz9 zz1, zz8
- #define zz10 zz1, zz9
- #define zz11 zz1, zz10
- //3.5us
- //16 ->56
- //rst 500us -> 9个0x0000;
- //rst wait 15-60us ->2个0xffff
- //rst read 0xffff read value
- // 9个0xffff;
- //, 0xffff
- //, 0xffff
- #define WRITE1 0x7fff, 0xffff
- #define WRITE0 0x0000, 0xffff
- //write 1
- //0x1fff, 0xffff
- //write 0
- //0x0000, 0x0fff
- //, 0xffff, 0xffff
- #define RD1 0x7fff, 0xffff
- #define RD2 RD1, RD1
- #define RD3 RD1, RD2
- #define RD4 RD1, RD3
- #define RD5 RD1, RD4
- #define RD6 RD1, RD5
- #define RD7 RD1, RD6
- #define RD8 RD1, RD7
- //read 0x7fff, 0xffff
- //0x2000 & ,如果== 0,
- //16
- //CC
- #define SKIPADDR WRITE0, WRITE0, WRITE1, WRITE1, WRITE0, WRITE0, WRITE1, WRITE1
- //44
- #define CONVERT WRITE0, WRITE0, WRITE1, WRITE0, WRITE0, WRITE0, WRITE1, WRITE0
- //BE 1011 1110
- #define RCMD WRITE0, WRITE1, WRITE1, WRITE1, WRITE1, WRITE1, WRITE0, WRITE1
- /*
- #define SKIPADDR WRITE1, WRITE1, WRITE0, WRITE0, WRITE1, WRITE1, WRITE0, WRITE0
- //44
- #define CONVERT WRITE0, WRITE1, WRITE0, WRITE0, WRITE0, WRITE1, WRITE0, WRITE0
- //BE 1011 1110
- #define RCMD WRITE1, WRITE0, WRITE1, WRITE1, WRITE1, WRITE1, WRITE1, WRITE0
- */
- #define BUFLENGTH (36 + 88 + 5 + 88)
- #define DSDATA1_LENGTH (27 + 16 * 2)
- #define DSDATA2_LENGTH (27 + 16 * 2 + 16 * 9)
- const u16t dsdata1[DSDATA1_LENGTH] = { ff7, zz11, ff9, SKIPADDR, CONVERT };
- const u16t dsdata2[DSDATA2_LENGTH] = { ff7, zz11, ff9, SKIPADDR, RCMD, RD8, RD8, RD8, RD8, RD8, RD8, RD8, RD8, RD8};
- #define MAXBUFLENGTH (DSDATA1_LENGTH + DSDATA2_LENGTH + DSDATA3_LENGTH + DSDATA4_LENGTH)
- #define DATA_OFFSET (DSDATA1_LENGTH + DSDATA2_LENGTH)
- static u8t _rbuf[10];
- static s32t index, rindex;
- //CRC = X8 + X5 + X4 + 1
- const u8t Crc8Table [256]={
- 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
- 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
- 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
- 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
- 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
- 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
- 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
- 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
- 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
- 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
- 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
- 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
- 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
- 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
- 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
- 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
- u8t GetCRC(u8t *str, u32t length) {
- u8t crc_data=0;
- u32t i;
- for(i=0;i<length;i++) { //查表校验
- crc_data = Crc8Table[crc_data^str[i]];
- }
- return (crc_data);
- }
- void spi_recive(void) {
- s32t t, r, i;
- while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RNE) == SET) {
- t = (u16t)SSP_ReceiveData(SSP0);
- if ((rindex >= 0) && ((rindex & 0x01) == 0)) {
- t &= 0x0f00;
- i = rindex / 16;
- r = _rbuf[i];
- r >>= 1;
- r &= 0x7f;
- if (t == 0x0f00) {
- r |= 0x80;
- }
- _rbuf[i] = r;
- }
- rindex++;
- }
- }
- s32t wd;
- void spi_process(void) {
- u8t temp;
- u8t TL,TH;
- s32t tem;
- TL = _rbuf[0]; // LSB
- TH = _rbuf[1]; // MSB
-
- if(TH>7) {
- TH=~TH;
- TL=~TL;
- temp=0;//温度为负
- }
- else {
- temp=1;//温度为正
- }
- tem=TH<<8 | TL; //获得不带符号位的11位温度值
- //转换 *0.625
- tem = tem*10000;
- tem = tem>>4;
- if(temp) {
- wd = tem;
- }
- else{
- wd = -tem;
- }
- }
- s32t spi_temperature(void){
- return wd;
- }
- #define FSM_INIT 0
- #define FSM_READY 1
- #define FSM_WAITFREE 2
- #define FSM_SEND_DATA1 3
- #define FSM_WAIT_DATA1_OK 4
- #define FSM_SEND_DATA2 5
- #define FSM_WAIT_DATA2_OK 6
- #define FSM_WAIT_CONVERT 7
- void spi_timerpoll(void) {
- if (_fsm == FSM_SEND_DATA1) {
- while((SSP_GetFlagStatus(SSP0, SSP_FLAG_TNF) == SET) && index < DSDATA1_LENGTH) {
- SSP_SendData(SSP0, dsdata1[index++]);
- }
- if(index >= (DSDATA1_LENGTH)) {
- timer_init(&_timer);
- _fsm = FSM_WAIT_DATA1_OK;
- }
- }
- else if (_fsm == FSM_SEND_DATA2) {
- spi_recive();
- while((SSP_GetFlagStatus(SSP0, SSP_FLAG_TNF) == SET) && index < DSDATA2_LENGTH) {
- SSP_SendData(SSP0, dsdata2[index++]);
- }
- spi_recive();
- if(index >= DSDATA2_LENGTH) {
- _fsm = FSM_WAIT_DATA2_OK;
- }
- }
- }
- void spi_service(void) {
- u32t temp_interrupt;
- temp_interrupt = (NVIC->ISPR[0]);
- (NVIC->ISPR[0]) = (u32t)0xFFFFFFFF;
- if ((_fsm == FSM_SEND_DATA1) || (_fsm == FSM_SEND_DATA2)) {
- (NVIC->ISPR[0]) = temp_interrupt;
- return;
- }
- (NVIC->ISPR[0]) = temp_interrupt;
- //CTX_EXIT();
- if (_fsm == FSM_READY) {
- if (timer_expired(&_timer, 9000)) {
- while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RNE) == SET) {
- SSP_ReceiveData(SSP0);
- }
- printf("\r\nGetting Started\r\n");
- index = 0;
- _fsm = FSM_SEND_DATA1;
- }
- }
- else if(_fsm == FSM_WAIT_DATA1_OK) {
- if (timer_expired(&_timer, 1000)) {
- while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RNE) == SET) {
- SSP_ReceiveData(SSP0);
- }
- index = 0;
- rindex = 16 * 9 - DSDATA2_LENGTH;
- _fsm = FSM_SEND_DATA2;
- }
- }
- else if(_fsm == FSM_WAIT_DATA2_OK) {
- spi_recive();
- if (SSP_GetFlagStatus(SSP0, SSP_FLAG_BSY)) {
- return;
- }
- spi_recive();
- /*
- t = _rbuf[0];
- t <<= 4;
- printf("SET __%d__%d\r\n", index, rindex);
- rindex /= 16;
- for(i = 0; i < rindex; i++){
- printf("%04X ", _rbuf[i]);
- }
- printf("\r\nSET END \r\n");*/
- if (GetCRC(_rbuf, 8) == _rbuf[8]) {
- spi_process();
- printf("Measuring success:%03d.%04d\r\n", wd / 10000, wd %10000);
- //printf("\r\nwd crc ok {%08d} \r\n", wd);
- }
- else {
- printf("Measurement fails\r\n");
- }
- _fsm = FSM_INIT;
- }
- else {
- timer_init(&_timer);
- _fsm = FSM_READY;
- }
- }
复制代码 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|