Вот сама задача
CODE
uint8_t dma_rec[8];
uint8_t dma_trans[8];
uint8_t ow_rec[20];
uint8_t ow_trans[20];
extern UART_HandleTypeDef huart2;
extern char* empty_str;
//*****************************************************************************
void OneWire_Task (void){
TTemp Temp;
uint8_t adr_DS1[8];
uint8_t adr_DS2[8];
restore_adr(EEPROM_ADR_DS1, adr_DS1);
restore_adr(EEPROM_ADR_DS2, adr_DS2);
while(1){
if(OW_Reset() == OW_OK){
ow_trans[0] = 0xCC;
ow_trans[1] = 0x44;
OW_Send(2);
vTaskDelay(1000);
DS1820_getConvertedValue(adr_DS1, &Temp.t1);
DS1820_getConvertedValue(adr_DS2, &Temp.t2);
xQueueOverwrite(Temp_QueueHandle, &Temp);
}
else{
vTaskDelay(1000);
}
}
}
Функция сброса и обнаружения импульса присутствия
CODE
uint8_t OW_Reset(void){
uint8_t ow_presence;
huart2.Init.BaudRate = 9600;
HAL_UART_Init(&huart2);
ow_trans[0] = 0xF0;
HAL_UART_Receive_DMA(&huart2, ow_rec, 1);
HAL_UART_Transmit_DMA(&huart2, ow_trans, 1);
xSemaphoreTake(OW_Complete_BinarySemHandle, portMAX_DELAY);
ow_presence = ow_rec[0];
huart2.Init.BaudRate = 115200;
HAL_UART_Init(&huart2);
if (ow_presence != 0xF0) return OW_OK; else return OW_NO_DEVICE;
}
uint8_t ow_presence;
huart2.Init.BaudRate = 9600;
HAL_UART_Init(&huart2);
ow_trans[0] = 0xF0;
HAL_UART_Receive_DMA(&huart2, ow_rec, 1);
HAL_UART_Transmit_DMA(&huart2, ow_trans, 1);
xSemaphoreTake(OW_Complete_BinarySemHandle, portMAX_DELAY);
ow_presence = ow_rec[0];
huart2.Init.BaudRate = 115200;
HAL_UART_Init(&huart2);
if (ow_presence != 0xF0) return OW_OK; else return OW_NO_DEVICE;
}
Отправка N байт по шине 1-wire
CODE
void OW_Send(uint8_t kol){
uint8_t i;
uint8_t rec_byte;
for(i = 0; i < kol; i++){
OW_convert(ow_trans[i],dma_trans);
HAL_UART_Receive_DMA(&huart2, dma_rec, 8);
HAL_UART_Transmit_DMA(&huart2, dma_trans, 8);
xSemaphoreTake(OW_Complete_BinarySemHandle, portMAX_DELAY);
rec_byte = OW_restore(dma_rec);
ow_rec[i] = rec_byte;
}
}
uint8_t i;
uint8_t rec_byte;
for(i = 0; i < kol; i++){
OW_convert(ow_trans[i],dma_trans);
HAL_UART_Receive_DMA(&huart2, dma_rec, 8);
HAL_UART_Transmit_DMA(&huart2, dma_trans, 8);
xSemaphoreTake(OW_Complete_BinarySemHandle, portMAX_DELAY);
rec_byte = OW_restore(dma_rec);
ow_rec[i] = rec_byte;
}
}
вот эта функция работает неправильно при втором вызове
CODE
uint8_t DS1820_getConvertedValue(uint8_t* adr, float* t){
uint8_t i;
float sign;
float a;
uint8_t ml_byte;
uint8_t st_byte;
uint8_t count_remain;
uint8_t count_per_c;
uint16_t temp_read;
uint8_t err = 0;
uint8_t crc;
OW_Reset();
ow_trans[0] = 0x55;
OW_Send(1);
vTaskDelay(5);
for(i = 0; i < 8; i++){
ow_trans[i] = *(adr + i);
}
OW_Send(8);
vTaskDelay(5);
ow_trans[0] = 0xBE;
OW_Send(1);
vTaskDelay(5);
for(i = 0; i < 9; i++){
ow_trans[i] = 0xFF;
}
OW_Send(9);
vTaskDelay(5);
ml_byte = ow_rec[0];
st_byte = ow_rec[1];
count_remain = ow_rec[6];
count_per_c = ow_rec[7];
crc = ow_rec[8];
temp_read = (((uint16_t)st_byte << 8) + (uint16_t)ml_byte) / 2;
if(temp_read & 0xFF00) sign = -1.0; else sign = 1.0;
if(sign == -1.0){
temp_read = ~temp_read + 1;
a = sign * (float)temp_read;
}
else{
a = (float)temp_read;
}
a = a - 0.25 + ((float)count_per_c - (float)count_remain) / (float)count_per_c;
*t = a;
return err;
}
uint8_t i;
float sign;
float a;
uint8_t ml_byte;
uint8_t st_byte;
uint8_t count_remain;
uint8_t count_per_c;
uint16_t temp_read;
uint8_t err = 0;
uint8_t crc;
OW_Reset();
ow_trans[0] = 0x55;
OW_Send(1);
vTaskDelay(5);
for(i = 0; i < 8; i++){
ow_trans[i] = *(adr + i);
}
OW_Send(8);
vTaskDelay(5);
ow_trans[0] = 0xBE;
OW_Send(1);
vTaskDelay(5);
for(i = 0; i < 9; i++){
ow_trans[i] = 0xFF;
}
OW_Send(9);
vTaskDelay(5);
ml_byte = ow_rec[0];
st_byte = ow_rec[1];
count_remain = ow_rec[6];
count_per_c = ow_rec[7];
crc = ow_rec[8];
temp_read = (((uint16_t)st_byte << 8) + (uint16_t)ml_byte) / 2;
if(temp_read & 0xFF00) sign = -1.0; else sign = 1.0;
if(sign == -1.0){
temp_read = ~temp_read + 1;
a = sign * (float)temp_read;
}
else{
a = (float)temp_read;
}
a = a - 0.25 + ((float)count_per_c - (float)count_remain) / (float)count_per_c;
*t = a;
return err;
}
каждый бит кодируем байтом
CODE
void OW_convert(uint8_t ow_byte, uint8_t* buf){
uint8_t i;
for(i = 0; i < 8; i++){
if((ow_byte >> i) & 0x01){
*(buf + i) = OW_1;
}
else{
*(buf + i) = OW_0;
}
}
}
uint8_t i;
for(i = 0; i < 8; i++){
if((ow_byte >> i) & 0x01){
*(buf + i) = OW_1;
}
else{
*(buf + i) = OW_0;
}
}
}
из 8 байт по USART делаем один
CODE
uint8_t OW_restore(uint8_t* buf){
uint8_t ow_byte;
uint8_t i;
ow_byte = 0;
for(i = 0; i < 8; i++){
ow_byte >>= 1;
if(buf[i] == OW_R_1) ow_byte |= 0x80;
else ow_byte &= (~0x80);
}
return ow_byte;
}
uint8_t ow_byte;
uint8_t i;
ow_byte = 0;
for(i = 0; i < 8; i++){
ow_byte >>= 1;
if(buf[i] == OW_R_1) ow_byte |= 0x80;
else ow_byte &= (~0x80);
}
return ow_byte;
}
CODE
читаем адрес датчика температуры
void DS1820_readROM(void){
uint8_t i;
OW_Reset();
ow_trans[0] = 0x33;
OW_Send(1);
vTaskDelay(5);
for(i = 0; i < 8; i++){
ow_trans[i] = 0xFF;
}
OW_Send(8);
}
после приема N байт по USART_DMA отдаем семафор
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
static portBASE_TYPE xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
if(huart == &huart2){
xSemaphoreGiveFromISR(OW_Complete_BinarySemHandle, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}
Не хотел работать HAL_USART_DMA в режиме NORMAL. Не вызывался колбек. Пришлось подправить.
[code]static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal mode*/
if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
{
huart->TxXferCount = 0;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
//__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
huart->State = HAL_UART_STATE_READY;
HAL_UART_TxCpltCallback(huart);
}
/* DMA Circular mode */
else
{
HAL_UART_TxCpltCallback(huart);
}
}
void DS1820_readROM(void){
uint8_t i;
OW_Reset();
ow_trans[0] = 0x33;
OW_Send(1);
vTaskDelay(5);
for(i = 0; i < 8; i++){
ow_trans[i] = 0xFF;
}
OW_Send(8);
}
после приема N байт по USART_DMA отдаем семафор
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
static portBASE_TYPE xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
if(huart == &huart2){
xSemaphoreGiveFromISR(OW_Complete_BinarySemHandle, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}
Не хотел работать HAL_USART_DMA в режиме NORMAL. Не вызывался колбек. Пришлось подправить.
[code]static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal mode*/
if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
{
huart->TxXferCount = 0;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
//__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
huart->State = HAL_UART_STATE_READY;
HAL_UART_TxCpltCallback(huart);
}
/* DMA Circular mode */
else
{
HAL_UART_TxCpltCallback(huart);
}
}