首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >5 ds18b20传感器只返回255

5 ds18b20传感器只返回255
EN

Stack Overflow用户
提问于 2022-09-29 12:28:12
回答 1查看 84关注 0票数 0

我正在研制一台pic18f67k22,试着让5 DS18B20温度传感器工作。第一个4会很好地读取温度,无论我给出的传感器值为4(或更高),读取温度时只返回255秒。这意味着硬件是好的,我们也可以读取日航的每一个传感器,只是不能用C。

我和我的同事们无法理解什么可能会导致这个问题。由于这个原因,我会先道歉,但这将是一个代码转储。

main.c:(main.h不包含任何内容)

代码语言:javascript
复制
/*
 * File:   main.c
 * Author: Wesley
 *
 * Created on September 6, 2022, 9:17 AM
 */

#include "fuses.h"

#include <stdbool.h>
#include <stdio.h>
#include <xc.h>

#include "clock.h"
#include "co2.h"
#include "delay.h"
#include "exti.h"
#include "i2c_drv.h"
#include "interrupt.h"
#include "LCDSerialTerminalMaster.h"
#include "onewire.h"
#include "pin.h"
#include "pwm.h"
#include "sim800.h"
#include "tempsensors.h"
#include "uart1.h"

uint8_t prevSec = 0;

void main(void)
{
    // disable comparators
    CM1CONbits.CON = 0;
    CM2CONbits.CON = 0;
    CM3CONbits.CON = 0;
    
    // disable analog input
    ADCON0bits.ADON = false;
    ANCON0 = 0;
    ANCON1 = 0;
    ANCON2 = 0;
    
    // turn 3v3 on to enable peripherals
    POWER_PIN_DIR = OUTPUT;
    POWER_PIN_OUT = LOW;
    
    INT_Init();
    UART1_Init();
    printf("_____START_____\r\n");
    
    I2C_Init();
    
    CLK_Init();
    LCD_Init();
    
    TEMP_Init();
    
    //SIM800_Init();//doesn't work, not receiving enough power consistently
    
    //needs to move to UI_Init
    CCP6CONbits.CCP6M   = 0b1100;       //PWM mode, single output for UI LEDs
    PWM_SetLed(255);
    
    printf("_____INIT DONE_____\r\n");
    
    while(1)
    {
        if(CLK_GetSec() != prevSec)
        {
            prevSec = CLK_GetSec();
            
            EXTI_Main(0);
            //SIM800_Main();//doesn't work, not receiving enough power consistently
            //CO2_Main();//all but scd30 get detected
            TEMP_Main();//doesn't work, last sensor(whichever gets highest value) always returns as not attached
            EXTI_Main(1);
            
            EXTI_Main(2);
            LCD_Write();
            
            EXTI_Main(3);
            
            EXTI_Main(4);
        }
    }
    
}

clock.c:(clock.h只包含原型)

代码语言:javascript
复制
/*
 * File:   clock.c
 * Author: Wesley
 *
 * Created on September 13, 2022, 2:10 PM
 */


#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <xc.h>

static uint8_t hour = 0;
static uint8_t min = 0;
static uint8_t sec = 0;
static volatile uint16_t ms = 0;

void CLK_Init(void)
{
    T3CONbits.TMR3CS = 0b00; // Source = Fosc/4
    T3CONbits.SOSCEN = 0b1;  // SOSC disabled
    T3CONbits.T3CKPS = 0b00; // Prescaler 1:1

    CCP4CONbits.CCP4M = 0b1011; // Compare Mode: Special Event Trigger, reset TMR3 on CCP4 match
    CCPTMRS1bits.C4TSEL = 0b01; // TMR3/TMR4

    // set compare value to 5000
    CCPR4L = 136;
    CCPR4H = 19;

    // Disable TMR3 interrupt.
    PIE2bits.TMR3IE = 0;

    // clear CCP4 interrupt.
    PIR4bits.CCP4IF = 0;

    // enable CCP4 interrupt.
    PIE4bits.CCP4IE = 1;
    IPR4bits.CCP4IP = 1;

    // Start the Timer by writing to TMRxON bit.
    T3CONbits.TMR3ON = 1;
}

void CLK_SetTime(uint8_t s, uint8_t m, uint8_t h)
{
    sec = s;
    min = m;
    hour = h;
}

void CLK_GetTime(char *buffer)
{
    sprintf(buffer, "%02hhu:%02hhu:%02hhu", hour, min, sec);
}

uint8_t CLK_GetSec(void)
{
    return sec;
}

uint16_t CLK_GetMs(void)
{
    return ms;
}

void CLK_ISR(void)
{   
    PIR4bits.CCP4IF = 0;
    ms++;
    if(ms == 1000)
    {
        ms = 0;
        sec++;
        if(sec == 60)
        {
            sec = 0;
            min++;
            if(min == 60)
            {
                min = 0;
                hour++;
                if(hour == 24)
                    hour = 0;
            }
        }
    }
}

delay.c(delay.h只包含原型)

代码语言:javascript
复制
/*
 * File:   delay.c
 * Author: Wesley
 *
 * Created on March 7, 2022, 1:08 PM
 */

#include "delay.h"

void Delay1us()
{
    //__asm("nop");//just the function call seems to be enough delay
}

void Delay2us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        );
}

void Delay3us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n");
}

void Delay4us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        );
}

void Delay5us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        );
}

void Delay6us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        );
}

void Delay7us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        );
}

void Delay8us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        );
}

void Delay9us()
{
    __asm(
    "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        "nop\n"
        );
}

void Delay10us(uint16_t amount)
{
    for (uint16_t i = 1; i < amount; i++)
    {
        Delay7us();
        __asm(
        "nop\n"
            "nop\n"
            );
    }
    Delay4us();
    __asm(
    "nop\n"
        );
}

void Delay1ms(uint16_t amount)
{
    for (uint16_t i = 1; i < amount; i++)
        Delay10us(99);
    Delay10us(98);
}

fuses.h:

代码语言:javascript
复制
/*
 * File:   config.h
 * Author: wesley
 *
 * Created on 6 september 2022, 10:11
 */

#ifndef FUSES_H
#define FUSES_H

// CONFIG1L
#pragma config SOSCSEL =    DIG // digital i/o on pin_c0 & pin_c1
#pragma config XINST =      OFF // Extended Instruction Set (Disabled)

// CONFIG1H
#pragma config FOSC =       HS2 //external oscillator

// CONFIG2L

// CONFIG2H
#pragma config WDTEN =      OFF // no watchdog

// CONFIG3L
#pragma config RTCOSC =     INTOSCREF // rtcc uses  internal oscillator

// CONFIG3H
#pragma config MCLRE =      OFF // reset externally

// CONFIG4L
#pragma config DEBUG =      OFF // no debugging

// CONFIG5L

// CONFIG5H

// CONFIG6L

// CONFIG6H

// CONFIG7L

// CONFIG7H



#include <xc.h>


#endif  /* FUSES_H */

C:(interintert.h只包含原型)

代码语言:javascript
复制
/*
 * File:   interrupt.c
 * Author: Wesley
 *
 * Created on September 6, 2022, 6:41 PM
 */

#include <stdbool.h>

#include "interrupt.h"

#include "clock.h"
//#include "i2c_drv.h"
#include "pin.h"
#include "uart1.h"

void INT_Init(void)
{
    // Enable Interrupt Priority Vectors
    IPEN = 1;

    // RCI - high priority
    UART2_RC_IP = 1;
    
    UART2_TX_IP = 0;

    MASTER_SYNC_IP = 1;
    
    INT_Toggle(true);
}

void INT_Toggle(bool toggle)
{
    INT_ToggleHigh(toggle);
    INT_ToggleLow(toggle);
}

void INT_ToggleHigh(bool toggle)
{
    INTCONbits.GIEH = toggle;
}

void INT_ToggleLow(bool toggle)
{
    INTCONbits.GIEL = toggle;
}

void __interrupt(high_priority) INT_InterruptManagerHigh(void)
{
    if(PIR4bits.CCP4IF)
        CLK_ISR();
    if(UART1_RC_IF)
        UART1_RC_ISR();
}

void __interrupt(low_priority) INT_InterruptManager(void)
{
    
}

C:(onewire.h只包含原型)

代码语言:javascript
复制
/*
 * File:   onewire.c
 * Author: Wesley
 *
 * Created on September 21, 2022, 4:57 PM
 */

#include <stdbool.h>

#include "delay.h"
#include "interrupt.h"
#include "tempsensors.h"
#include "pin.h"

//debug
#include "uart1.h"

static bool GetPin(TEMP_sensor_t sensor)
{
    switch(sensor)
    {
        case T1:
            return T1_IN;
        case T2:
            return T2_IN;
        case T3:
            return T3_IN;
        case T4:
            return T4_IN;
        case T5:
            return T5_IN;
        default://suppresses warning
            return false;
    }
}

static void SetDir(TEMP_sensor_t sensor, bool value)
{
    switch(sensor)
    {
        case T1:
            T1_DIR = value;
            break;
        case T2:
            T2_DIR = value;
            break;
        case T3:
            T3_DIR = value;
            break;
        case T4:
            T4_DIR = value;
            break;
        case T5:
            T5_DIR = value;
            break;
        default://suppresses warning
            break;
    }
}

static void SetLat(TEMP_sensor_t sensor, bool value)
{
    switch(sensor)
    {
        case T1:
            T1_OUT = value;
            break;
        case T2:
            T2_OUT = value;
            break;
        case T3:
            T3_OUT = value;
            break;
        case T4:
            T4_OUT = value;
            break;
        case T5:
            T5_OUT = value;
            break;
        default://suppresses warning
            break;
    }
}

static void SetPin(TEMP_sensor_t sensor, bool value)
{
    switch(sensor)
    {
        case T1:
            T1_IN = value;
            break;
        case T2:
            T2_IN = value;
            break;
        case T3:
            T3_IN = value;
            break;
        case T4:
            T4_IN = value;
            break;
        case T5:
            T5_IN = value;
            break;
        default://suppresses warning
            break;
    }
}

void OW_WriteBit(TEMP_sensor_t sensor , bool data)
{
    INT_Toggle(false);
    SetLat(sensor, LOW);
    SetDir(sensor, OUTPUT);
    Delay10us(1);
    if(data)
        SetDir(sensor, INPUT);
    Delay10us(8);
    SetDir(sensor, INPUT);
    Delay10us(1);
    INT_Toggle(true);
}

void OW_ReadBit(TEMP_sensor_t sensor, uint8_t *output)
{
    INT_Toggle(false);
    SetLat(sensor, LOW);
    SetDir(sensor, OUTPUT);
    Delay10us(1); 
    SetDir(sensor, INPUT);
    Delay10us(1);
    *output = GetPin(sensor);
    Delay10us(7);
    INT_Toggle(true);
}

void OW_WriteByte(TEMP_sensor_t sensor, uint8_t data)
{
    for(uint8_t i = 0; i < 8; i++)
    {
        OW_WriteBit(sensor, data & 1);
        data >>= 1;
    }
    SetLat(sensor, HIGH);
    SetDir(sensor, OUTPUT);
}

void OW_ReadByte(TEMP_sensor_t sensor, uint8_t *output)
{
    uint8_t b;//bit
    for(uint8_t i = 0; i < 8; i++)
    {
        *output >>= 1;
        OW_ReadBit(sensor, &b);
        *output += b << 7;
    }
    SetLat(sensor, HIGH);
    SetDir(sensor, OUTPUT);
}

void OW_Reset(TEMP_sensor_t sensor)
{
    SetLat(sensor, LOW);
    SetDir(sensor, OUTPUT);
    Delay10us(70);
    SetDir(sensor, INPUT);
    Delay10us(70);
}

H(pin.c不存在)

代码语言:javascript
复制
/* 
 * File:   pin.h
 * Author: Wesley
 *
 * Created on September 6, 2022, 1:00 PM
 *
 *
 *
 * PIC18F67K22 pin connections
 * nr    pin                 function    signal name
 * 1     RE1/!WR/P2C         io          MUX_A_DIR      serial multiplexer address 2
 * 2     RE0/!RD/P2D         io          MUX_B_DIR      serial multiplexer address 1
 * 3     RG0/ECCP3/P3A       io          SPARE7         to spare connector
 * 4     RG1/TX2/CK2         io          WF_RX          wifi UART receive
 * 5     RG2/RX2/DT2         io          WF_TX          wifi UART transmit
 * 6     RG3/CCP4/P3D        io          BUZZER         buzzer via CCP4
 * 7     !MCLR               in          !MCLR          reset
 * 8     RG4/CCP5/T7CKI      io          RPM_FAN2       fan RPM VIA TMR7
 * 9     VSS                 pwr         GND            GND
 * 10    VDDCORE/VCAP        pwr         VDD_CORE       to capacitor
 * 11    RF7/!SS1            io          SEND/!REC      send_rec to ADM3493, RS485
 * 12    RF6/AN11            io          LEDS           green/red LEDs
 * 13    RF5/AN10/CVREF      io          SPARE5         to spare connector
 * 14    RF4/AN9             io          SPARE3         to spare connector
 * 15    RF3/AN8             io          SPARE4         to spare connector
 * 16    RF2/AN7/C1OUT       io          SPARE6         to spare connector
 * 17    RF1/AN6/C2OUT       io          SPARE9         to spare connector
 * 18    ENVREG              in          +5V            +5V
 * 19    AVDD                pwr         +5V            +5V
 * 20    AVSS                pwr         GND            GND
 * 21    RA3/AN3/VREF+       io          SPARE8         to spare connector
 * 22    RA2/AN2/VREF-       io          DS18B20_T5     DS18B20 sensor 5, aka T2A
 * 23    RA1/AN1             io          DS18B20_T4     DS18B20 sensor 4
 * 24    RA0/AN0             io          SPARE10        to spare connector
 * 25    VSS                 pwr         GND            GND
 * 26    VDD                 pwr         +5V            +5V
 * 27    RA5/AN4             io          DS18B20_T1     DS18B20 sensor 1
 * 28    RA4/T0CK            io          DS18B20_T3     DS18B20 sensor 3
 * 29    RC1/T1OSI/ECCP2/P2A io          PWM_FAN1       PWM fan 1 via ECCP2
 * 30    RC0/T1OSO/T13CKI    io          DS18B20_T2     DS18B20 sensor 2
 * 31    RC6/TX1/CK1         io          MUX_RX         mux UART transmit
 * 32    RC7/RX1/DT1         io          MUX_TX         mux UART receive
 * 33    RC2/ECCP1/P1A       io          PWM_FAN2       PWM fan 2 via ECCP1
 * 34    RC3/SCK1/SCL1       io          SCL            I2C
 * 35    RC4/SDI1/SDA1       io          SDA            I2C
 * 36    RC5/SDO1            io          COUPLE_CHECK   resistance measurement thermocouple
 * 37    RB7/KBI2/PGD        io          PGD            ICSP
 * 38    VDD                 pwr         +5V            +5V
 * 39    OSC1/CLKI           in          OSC1           20 Mhz crystal
 * 40    OSC2/CLKO           out         OSC2           20 Mhz crystal
 * 41    VSS                 pwr         GND            GND
 * 42    RB6/KBI2/PGC        io          PGC            ICSP
 * 43    RB5/KBI1            io          STERM          LCD and keyboard
 * 44    RB4/KBI0            io          HEAT_          to heater triac optocoupler
 * 45    RB3/INT3            io          RELAY          powers heater
 * 46    RB2/INT2            io          ZERO_CROSS     230V AC zero cross timing
 * 47    RB1/INT1            io          TRIAC_CHECK    heater voltage
 * 48    RB0/INT0/FLT0       io          RF_DATA        incoming 433 Mhz remote control
 * 49    RD7/PSP7/!SS2       io          UI19           auto button
 * 50    RD6/PSP6/SCK2/SCL2  io          UI_SCK         UI LEDs clock
 * 51    RD5/PSP5/SDI2/SDA2  io          SPARE11        not used
 * 52    RD4/PSP4/SDO2       io          UI_DATA        UI LEDs data
 * 53    RD3/PSP3            io          SPARE12        not used
 * 54    RD2/PSP2            io          SPARE14        not used
 * 55    RD1/PSP1/T5CKI      io          RPM_FAN1       fan RPM VIA TMR5
 * 56    VSS                 pwr         GND            GND
 * 57    VDD                 pwr         +5V            +5V
 * 58    RD0/PSP0            io          !POWER_SENSORS MAX893 sensor power cycle
 * 59    RE7/ECCP2/P2A       io          !FAULT         MAX893 overcurrent
 * 60    RE6/P1B             io          UI_PWM         UI LEDs brightness via CCP6
 * 61    RE5/P1C             io          SIM800_POW     SIM800 power cycle
 * 62    RE4/P3B             io          WF_RESET       ESP32 AP mode
 * 63    RE3/P3C             io          UI5            UI flowmin button
 * 64    RE2/!CS/P2B         io          UI3            UI flowplus button
 */

#ifndef PIN_H
#define PIN_H

#include <xc.h>

#define OUTPUT          0
#define INPUT           1

#define LOW             0
#define HIGH            1

//FAN
#define FAN1_IN         PORTDbits.RD1
#define FAN1_DIR        TRISDbits.TRISD1
#define FAN1_PWM        CCPR2L
#define FAN1_PWM_IN     PORTCbits.RC1
#define FAN1_PWM_OUT    LATCbits.LC1
#define FAN1_PWM_DIR    TRISCbits.TRISC1
#define FAN2_IN         PORTGbits.RG4
#define FAN2_DIR        TRISGbits.TRISG4
#define FAN2_PWM        CCPR1L
#define FAN2_PWM_IN     PORTCbits.RC2
#define FAN2_PWM_OUT    LATCbits.LC2
#define FAN2_PWM_DIR    TRISCbits.TRISC2

//INTERRUPT
#define IPEN            RCONbits.IPEN
#define MASTER_SYNC_IP  IPR1bits.SSP1IP
#define RTC_IF          PIR3bits.RTCCIF
#define RTC_IP          IPR3bits.RTCCIP
#define UART2_RC_IF     PIR3bits.RC2IF
#define UART2_RC_IP     IPR3bits.TX2IP
#define UART2_TX_IF     PIR3bits.RC2IF
#define UART2_TX_IP     IPR3bits.TX2IP

//LCD
#define LCD_PIN_DIR     TRISBbits.TRISB5
#define LCD_PIN_OUT     LATBbits.LB5
#define LCD_PIN_IN      PORTBbits.RB5

//MAIN
#define LED_DIM         CCPR6L
    //ICSP
    #define PGC         PORTBbits.RB6
    #define PGC_DIR     TRISBbits.TRISB6
    #define PGD         PORTBbits.RB7
    #define PGD_DIR     TRISBbits.TRISB7

//ONEWIRE
#define T1_IN           PORTAbits.RA5
#define T1_OUT          LATAbits.LA5
#define T1_DIR          TRISAbits.TRISA5
#define T2_IN           PORTCbits.RC0
#define T2_OUT          LATCbits.LC0
#define T2_DIR          TRISCbits.TRISC0
#define T3_IN           PORTAbits.RA4
#define T3_OUT          LATAbits.LA4
#define T3_DIR          TRISAbits.TRISA4
#define T4_IN           PORTAbits.RA1
#define T4_OUT          LATAbits.LA1
#define T4_DIR          TRISAbits.TRISA1
#define T5_IN           PORTAbits.RA2
#define T5_OUT          LATAbits.LA2
#define T5_DIR          TRISAbits.TRISA2

//PIEZO
#define BEEP_IN         PORTGbits.RG3
#define BEEP_DIR        TRISGbits.TRISG3

//POWER
#define POWER_IN        PORTDbits.RD0
#define POWER_PIN_DIR   TRISDbits.TRISD0
#define POWER_PIN_OUT   LATDbits.LD0

//RF
#define RF_IN           PORTBbits.RB0
#define RF_DIR          TRISBbits.TRISB0

//RTC
#define RTC_IE          PIE3bits.RTCCIE

//SIM
#define SIM_POWER       PORTEbits.RE5
#define SIM_POWER_OUT   LATEbits.LE5
#define SIM_POWER_DIR   TRISEbits.TRISE5

//TEMP

//TCPL
#define TCPL_CHECK      PORTCbits.RC5
#define TCPL_CHECK_DIR  TRISCbits.TRISC5

//UART1
#define MUX_A           LATEbits.LE1
#define MUX_A_DIR       TRISEbits.TRISE1
#define MUX_B           LATEbits.LE0
#define MUX_B_DIR       TRISEbits.TRISE0
#define MUX_RC_DIR      TRISCbits.TRISC6
#define MUX_TX_DIR      TRISCbits.TRISC7

#define SEND_REC        LATFbits.LF7
#define SEND_REC_DIR    TRISFbits.TRISF7

#define UART1_RC_IE     PIE1bits.RC1IE
#define UART1_RC_IF     PIR1bits.RC1IF
#define UART1_RC_IP     IPR1bits.RC1IP
#define UART1_TX_IF     PIR1bits.TX1IF
#define UART1_TX_IP     IPR1bits.TX1IP

//UART2
#define WF_RESET        PORTEbits.RE4
#define WF_RESET_DIR    TRISEbits.TRISE4
#define WF_RC           PORTGbits.RG1
#define WF_RC_DIR       TRISGbits.TRISG1
#define WF_TX           PORTGbits.RG2
#define WF_TX_DIR       TRISGbits.TRISG2
#define UART2_RC_IE     PIE3bits.RC2IE
#define UART2_TX_IDLE   TXSTA2bits.TRMT

#endif  /* PIN_H */

诱惑力c:

代码语言:javascript
复制
    /*
 * File:   tempsensors.c
 * Author: Wesley
 *
 * Created on September 21, 2022, 4:40 PM
 */

#include <stdbool.h>
#include <stdint.h>

#include "onewire.h"
#include "pin.h"
#include "tempsensors.h"

//debug
#include "uart1.h"

static uint8_t scratchpad[TEMP_SENSOR_AMOUNT][9];
static int16_t value[TEMP_SENSOR_AMOUNT];

static bool reading = true;

//static uint8_t crc8(uint8_t* data, uint8_t len)
//{
//    uint8_t crc = 0;
//    while (len--)
//    {
//        uint8_t inbyte = *data++;
//        for (uint8_t i = 8; i; i--)
//        {
//            uint8_t mix = (crc ^ inbyte) & 0x01;
//            crc >>= 1;
//            if (mix) crc ^= 0x8C;
//            inbyte >>= 1;
//        }
//    }
//    return crc;
//}

//BytesToRead == 8 = read ROM ID
//BytesToRead == 9 = read hw scratchpad
static void Read(uint8_t sensor, uint8_t BytesToRead)
{
    // read a number of bytes and calculate the CRC value of
    // the complete group  
    for(uint8_t i = 0; i < BytesToRead; i++)
        OW_ReadByte(sensor, &scratchpad[sensor][i]);
    
    if(BytesToRead == 9 && scratchpad[sensor][4] == 0xFF && scratchpad[sensor][5] == 0xFF && 
       scratchpad[sensor][6] == 0xFF && scratchpad[sensor][7] == 0xFF && scratchpad[sensor][8] == 0xFF)
    {
        printf("T%hhu NOT ATTACHED\r\n", sensor + 1);
        // probe is not present, all read to 0xFF
        // set the CRC value to false, and reset temp with error scale 99°c
        scratchpad[sensor][0] = 198;
    }
}

static void SkipRom(uint8_t sensor)
{
    OW_Reset(sensor);
    OW_WriteByte(sensor, 0xCC);
}

//converts sensor temp to readable temp
static void Convert(uint8_t sensor)
{
    SkipRom(sensor);
    OW_WriteByte(sensor, 0x44); // init temp conversion cmd
}

static void ReadTemp(uint8_t sensor)
{
    SkipRom(sensor);
    OW_WriteByte(sensor, 0xBE);
    Read(sensor, 9);
}

void TEMP_Init(void)
{
    T1_OUT = LOW;
    T1_DIR = INPUT;
    T2_OUT = LOW;
    T2_DIR = INPUT;
    T3_OUT = LOW;
    T3_DIR = INPUT;
    T4_OUT = LOW;
    T4_DIR = INPUT;
    T5_OUT = LOW;
    T5_DIR = INPUT;
}

void TEMP_Main(void) 
{
    if(reading)
    {
        for(uint8_t sensor = 0; sensor < TEMP_SENSOR_AMOUNT; sensor++)
        {
            ReadTemp(sensor);
            value[sensor] = (((int16_t)(scratchpad[sensor][1] << 8) + scratchpad[sensor][0]) * 10) >> 4;
            printf("T%u:%hu\t%hu\r\n", sensor + 1, scratchpad[sensor][1], scratchpad[sensor][0]);
            printf("T%u:%hu\r\n", sensor + 1, value[sensor]);
        }
    }
    else
    {
        for(uint8_t sensor = 0; sensor < TEMP_SENSOR_AMOUNT; sensor++)
            Convert(sensor);
    }
    reading = !reading;
}

int16_t TEMP_GetValue(uint8_t sensor)
{
    return value[sensor];
}

uart1.c 1.c:(uart1.c 1.h只包含原型)

代码语言:javascript
复制
/*
 * File:   uart1.c
 * Author: Wesley
 *
 * Created on September 6, 2022, 3:43 PM
 */

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <xc.h>

#include "uart1.h"

#include "delay.h"
#include "pin.h"

UART1_direction_t dir;

uint8_t *UART1_simBuf;
uint8_t UART1_simPtr = 0;

//debug 
char c;

static void SetDirection(UART1_direction_t direction)
{
    dir = direction;
    MUX_A = (dir & 1);
    MUX_B = (dir & 2) != 0;
    Delay10us(2);
}

static void WriteChar(char data, uint8_t len)
{
    while(!UART1_TX_IF);
    TXREG1 = data;
}

static void WriteString(char *data, uint8_t len)
{
    for(uint8_t i = 0; i < len; i++)
    {
        while(!UART1_TX_IF);
        TXREG1 = data[i];
    }
}

void UART1_Init(void) 
{
    MUX_RC_DIR = OUTPUT;
    MUX_TX_DIR = INPUT;
    MUX_A_DIR = OUTPUT;
    MUX_B_DIR = OUTPUT;
    
    //according to JAL
    BAUDCON1 = 0b01001000;// RCIDL, BRG16
    TXSTA1 = 0b00100100;// TXEN, BRGH
    RCSTA1 = 0b10010000; //SPEN, CREN
    //SPBRG1 = 42; //115200
    SPBRG1 = 0x08;// BAUD 9600
    SPBRGH1 = 0x02; 
    SEND_REC_DIR = OUTPUT;
    
    UART1_RC_IE = true;
    UART1_RC_IP = HIGH;
    UART1_TX_IP = LOW;
    
    SetDirection(UART1_SIM);
}

void putch(char data)
{
    SetDirection(UART1_FTDI);
    WriteChar(data, 1);
}

void UART1_WriteSim(char *data)
{
    SetDirection(UART1_SIM);
    WriteString(data, (uint8_t)(strchr(data, '\0') - data));
}

void UART1_RC_ISR(void)
{
    if(RCSTA1bits.OERR)//if overflow, restart
    {
        RCSTA1bits.CREN = 0;
        RCSTA1bits.CREN = 1;
        return;
    }
    
    c = RCREG1;
    switch(dir)
    {
        case UART1_SIM:
//            if(UART1_simPtr < SIM_BUFFER_SIZE)
//                UART1_simBuf[UART1_simPtr++] = c;
            break;
        case UART1_RS485:
            break;
        case UART1_FTDI:
            break;
        case UART1_DUST_D1:
            break;
    }
}

char UART1_GetLast(void)
{
    return c;
}

再次抱歉抛出所有代码,但我们有点绝望。如果有任何问题回覆,请问,我将尽力回答。

EN

回答 1

Stack Overflow用户

发布于 2022-09-30 08:09:58

不确定这是否是造成此问题的原因,但这里确实有一个bug:

(int16_t)(scratchpad[sensor][1] << 8)

由于您使用的是8位,所以uint8_t操作数scratchpad[sensor][1]将被隐式提升到int,即16位(参见Implicit type promotion rules)。在此之后,您可能会将数据转换为符号位,从而导致未定义的行为。后来右转,你也会因此而遇到类似的问题。

int16_t的转换是没有意义的--由于隐式的提升,结果将已经是这种类型了。但是,您需要确保位移位总是发生在操作数上,操作数是uint16_t!不是uint8_t,不是int16_t。与流行的观点相反,在C中编写8位代码并不是那么简单。16位int类型意味着您需要很好地了解所有隐式类型升级规则。

为了提高可读性,我正在将杂乱无章的“一行”拆分成几个代码:

代码语言:javascript
复制
uint16_t tmp = (uint16_t)scratchpad[sensor][1] << 8;
tmp += scratchpad[sensor][0];
tmp *= 10;
value[sensor] = (int16_t) (tmp >> 4);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73895561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档