stm32f103c8t6
Настраивал вывод PA9 как альтернативная функция open drain
Применение usart1+dma
1wire.h
Код:
#ifndef _1WIRE_H #define _1WIRE_H #include "stm32f1xx.h" #define OW_SEND_RESET 1 #define OW_NO_RESET 2 #define OW_OK 1 #define OW_ERROR 2 #define OW_NO_DEVICE 3 #define OW_NO_READ 0xff #define OW_READ_SLOT 0xff #define APB1CLK 72000000UL #define BAUD 115200UL #define BAUD2 9600UL void OW_Init(void); uint8_t OW_Reset(void); uint8_t OW_Send(uint8_t sendReset, char *command, uint8_t cLen, uint8_t *data, uint8_t dLen, uint8_t readStart); char DLcrc8 (uint8_t *pData,char counterBytes ); #endif //1WIRE_H
1wire.c
Код:
#include "1wire.h" // Буфер для приема/передачи по 1-wire uint8_t ow_buf[8]; #define OW_0 0x00 #define OW_1 0xff #define OW_R_1 0xff //----------------------------------------------------------------------------- // функция преобразует один байт в восемь, для передачи через USART // ow_byte - байт, который надо преобразовать // ow_bits - ссылка на буфер, размером не менее 8 байт //----------------------------------------------------------------------------- void OW_toBits(uint8_t ow_byte, uint8_t *ow_bits) { uint8_t i; for (i = 0; i < 8; i++) { if (ow_byte & 0x01) { *ow_bits = OW_1; } else { *ow_bits = OW_0; } ow_bits++; ow_byte = ow_byte >> 1; } } //----------------------------------------------------------------------------- // обратное преобразование - из того, что получено через USART опять собирается байт // ow_bits - ссылка на буфер, размером не менее 8 байт //----------------------------------------------------------------------------- uint8_t OW_toByte(uint8_t *ow_bits) { uint8_t ow_byte, i; ow_byte = 0; for (i = 0; i < 8; i++) { ow_byte = ow_byte >> 1; if (*ow_bits == OW_R_1) { ow_byte |= 0x80; } ow_bits++; } return ow_byte; } //----------------------------------------------------------------------------- // инициализиция USART и DMA //----------------------------------------------------------------------------- void OW_Init(void) { //тактирование usart1 от шины PLC1 с частатой шины 72 Мгц RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; RCC->APB2ENR|=RCC_APB2ENR_USART1EN; RCC->APB2ENR|=RCC_APB2ENR_IOPAEN; GPIOA->CRH&= ~(GPIO_CRH_MODE9); GPIOA->CRH|=GPIO_CRH_MODE9_0|GPIO_CRH_MODE9_1; GPIOA->CRH&= ~(GPIO_CRH_CNF9); GPIOA->CRH|= GPIO_CRH_CNF9_0|GPIO_CRH_CNF9_1; USART1->BRR =(APB1CLK+BAUD/2)/BAUD; // 115200 USART1->CR1 |= USART_CR1_TE |USART_CR1_RE; // USART1->CR3 |=USART_CR3_HDSEL; RCC->AHBENR |=RCC_AHBENR_DMA1EN; // DMA1_Channel5->CPAR = (uint32_t) &(USART1->DR); DMA1_Channel5->CMAR = (uint32_t) ow_buf; // DMA1_Channel5->CNDTR = 0x08; // DMA1_Channel5->CCR=0; DMA1_Channel5->CCR = DMA_CCR_MINC//DMA_CCR5_MINC //DMA_CCR_CIRC| //DMA_CCR_DIR ; DMA1_Channel4->CPAR = (uint32_t)&(USART1->DR); DMA1_Channel4->CMAR = (uint32_t) ow_buf; // DMA1_Channel4->CNDTR = 0x08; // DMA1_Channel4->CCR=0; DMA1_Channel4->CCR = DMA_CCR_MINC|//DMA_CCR6_MINC| //DMA_CCR_CIRC| DMA_CCR_DIR//DMA_CCR6_DIR ; } //----------------------------------------------------------------------------- // осуществляет сброс и проверку на наличие устройств на шине //----------------------------------------------------------------------------- uint8_t OW_Reset() { uint8_t ow_presence; USART1->CR1 &= ~USART_CR1_UE; // USART1 USART1->BRR =(APB1CLK+BAUD2/2)/BAUD2; //usart1 9600 USART1->CR1 |= USART_CR1_UE; // USART1 //USART1->ICR|=USART_ICR_TCCF; USART1->SR|=USART_SR_TC; USART1->DR= 0xf0; while(!(USART1->SR & USART_SR_TC)); ow_presence = USART1->DR; USART1->CR1 &= ~USART_CR1_UE; // USART1 USART1->BRR =(APB1CLK+BAUD/2)/BAUD; //usart1 115200 USART1->CR1 |= USART_CR1_UE; // USART1 if (ow_presence != 0xf0) { return OW_OK; } return OW_NO_DEVICE; } //----------------------------------------------------------------------------- // процедура общения с шиной 1-wire // sendReset - посылать RESET в начале общения. // OW_SEND_RESET или OW_NO_RESET // command - массив байт, отсылаемых в шину. Если нужно чтение - отправляем OW_READ_SLOTH // cLen - длина буфера команд, столько байт отошлется в шину // data - если требуется чтение, то ссылка на буфер для чтения // dLen - длина буфера для чтения. Прочитается не более этой длины // readStart - с какого символа передачи начинать чтение (нумеруются с 0) // можно указать OW_NO_READ, тогда можно не задавать data и dLen //----------------------------------------------------------------------------- //OW_Send(OW_SEND_RESET, "\xcc\xbe\xff\xff", 4, buf, 2, 2); uint8_t OW_Send(uint8_t sendReset, char *command, uint8_t cLen, uint8_t *data, uint8_t dLen, uint8_t readStart) { if (sendReset == OW_SEND_RESET) { if (OW_Reset() == OW_NO_DEVICE) { return OW_NO_DEVICE; } } while (cLen > 0) { OW_toBits(*command, ow_buf); command++; cLen--; USART1->CR1 |= USART_CR1_UE; // USART1 DMA1_Channel5->CNDTR = 0x08; DMA1_Channel4->CNDTR = 0x08; DMA1_Channel5->CCR |= DMA_CCR_EN; //DMA_CCR5_EN; DMA1_Channel4->CCR |= DMA_CCR_EN; //DMA_CCR4_EN; USART1->CR3|=USART_CR3_DMAR | USART_CR3_DMAT; while(!(DMA1->ISR & DMA_ISR_TCIF5)){}; DMA1->IFCR |= DMA_IFCR_CTCIF5; // прием завершен DMA1_Channel5->CCR &= ~DMA_CCR_EN; //DMA_CCR5_EN; DMA1_Channel4->CCR &= ~DMA_CCR_EN; //DMA_CCR4_EN; USART1->CR3&= ~(USART_CR3_DMAR | USART_CR3_DMAT); USART1->CR1 &= ~USART_CR1_UE; // USART1 // if (readStart == 0 && dLen > 0) { *data = OW_toByte(ow_buf); data++; dLen--; } else { if (readStart != OW_NO_READ) { readStart--; } } } return OW_OK; } char DLcrc8 (uint8_t *pData,char counterBytes ) { char crc; char data; char i,fb; crc =0; // Инициализируем do // Просматриваем весь массив { data = *pData++; // Читаем байт for (i=0;i<8;i++) // счетчик битов в байте { fb =crc ^ data; //восемь бит,начинаем с конца с перевнутым полиномом fb&=1; // 100110001,то есть будет 100011001,смотрим на младший бит crc >>= 1; //если с датой обои data >>=1; if (fb == 1)crc^=0x8c;// полином, мля 1000 1100 } } while (counterBytes-- ); return crc; }
Подсчет crc и выдача если что то с датчиком. Правда вот может быть равен crc нулю ? потому что usart не запускается,пока не будет перепада на входе PA9 и потому будет crc по нулям crc и buf. Ошибку не показывает потому.
Пример программы main :
Код:
char temp,temp1; uint8_t buf[10]; char txt[10]; uint8_t CRC_ds,error_ds,i; OW_Send(OW_SEND_RESET, "\xcc\xbe\xff\xff\xff\xff\xff\xff\xff\xff\xff", 11, buf, 11, 2) ;//2); CRC_ds=DLcrc8(buf,7); //функция вычисления контрольной суммы if(CRC_ds==buf[8]&&!(CRC_ds==0)) error_ds=1; //сравниваем теперь и если норм то возращается единичка else error_ds=0; if(error_ds) { temp = ( ((buf[1]&0x07)<<4)|(buf[0]>>4)); temp1=(buf[0]&0x0F); temp1=((temp1<<1)+(temp1<<3)); temp1=(temp1>>4); sprintf(txt," T=%d.%d C ",temp,temp1); ssd1306_Puts(txt,1); // text and stroka ssd1306_update(1); } else { sprintf(txt," T=Error "); ssd1306_Puts(txt,1); // text and stroka ssd1306_update(1); } for(i=0;i<9;i++) buf[i]=0; CRC_ds=0; OW_Send(OW_SEND_RESET, "\xcc\x44", 2, NULL, NULL, OW_NO_READ); osDelay(1000);
Отредактировано CERGEI (2017-04-06 08:02:02)