Untitled

 avatar
unknown
plain_text
a month ago
4.1 kB
2
Indexable
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>

#define DATA_PIN   PB6  // DRDY/DOUT (Data Output & Ready)
#define SCK_PIN    PB7  // SCLK (Clock)
#define PDWN_PIN   PB4  // Power Down
#define NOP() __asm__ __volatile__("nop")

#define DISP_CS PE2
#define Digit0_turn 0x23
#define Digit1_turn 0x22
#define Digit2_turn 0x21
#define Digit3_turn 0x20
#define Digit0_torque 0x27
#define Digit1_torque 0x26
#define Digit2_torque 0x25
#define Digit3_torque 0x24

unsigned char digits [13]= {0x7E,   /* 0 */
							0x30,   /* 1 */
							0x6D,   /* 2 */
							0x79,   /* 3 */
							0x33,   /* 4 */
							0x5B,   /* 5 */
							0x5F,   /* 6 */
							0x70,   /* 7 */
							0x7F,   /* 8 */
							0x7B,   /* 9 */
							0x7C,   /* L */
							0x5C,   /* o */
							0x38};  /* b */

char ASCII[11] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'};

float Convert_To_Torque(long value) {
	return ((float)value / 524288.0) * 10.0; // Scale ADC value to ±10Nm range
}
void Write_Display(unsigned char Disp_data_H, unsigned char Disp_data_L)
{
	DDRB |= (1 << PB5) | (1 << PB7) | (1 << PB4); // SCK, MOSI, SS as outputs
	DDRB &= ~(1 << PB6);  // MISO as input
	SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); // Enable SPI, Master mode, Fosc/16
	DDRE |= (1 << PE2);      //Enable ISP, Master, set SPCR register, fosc/16
	SPSR = 0x00;
	PORTE &= ~(1 << PE2); //(0 << PORTC4);      // DISP-CS = 0 PORTC=PORTC & 0xEF; //
	NOP();  // No operation delay
	NOP();  // No operation delay
	SPDR = Disp_data_H; //Data high byte
	while(!(SPSR & 0x80))
	; // Wait until SPIF bit in SPI Status register SPSR is zero
	SPDR = Disp_data_L; //Data low byte
	while(!(SPSR & 0x80))
	; // Wait until SPIF bit in SPI Status register SPSR is zero
	NOP();  // No operation delay
	NOP();  // No operation delay
	PORTE |= (1 << PE2); //(1 << PORTC4);      // DISP-CS = 1
}

void updateTorque(uint32_t data) {
	long adc_data = data;
	float torque = Convert_To_Torque(adc_data);
	//float torque = 213.4;
	int torqueVal = (int)torque;
	int decimal = ((int)(torque * 10)) % 10;
	int ones = (torqueVal / 1) % 10;
	int tens = (torqueVal / 10) % 10;
	int hundreds = (torqueVal / 100) % 10;
	
	Write_Display(Digit0_torque, digits[decimal]);
	Write_Display(Digit1_torque, digits[ones]);
	Write_Display(Digit2_torque, digits[tens]);
	Write_Display(Digit3_torque, digits[hundreds]);
	
	//Write_Display(Digit0_turn, digits[decimal]);
	//Write_Display(Digit1_turn, digits[ones]);
	//Write_Display(Digit2_turn, digits[tens]);
	//Write_Display(Digit3_turn, digits[hundreds]);
}

int main(void)
{
    DDRB &= ~(1 << DATA_PIN);  // Set DATA as input
    DDRB |= (1 << SCK_PIN);    // Set SCK as output
    DDRD |= (1 << PDWN_PIN);   // Set PDWN as output
    
    PORTD |= (1 << PDWN_PIN);  // Set PDWN high (normal operation)
    PORTB &= ~(1 << SCK_PIN);  // Set SCK low initially
	
	Write_Display(0x04, 0x01); // Configuration
	Write_Display(0x01, 0x00); // No Decode mode
	Write_Display(0x02, 0x0F); // Intensity
	Write_Display(0x03, 0x07); // Scan Limit
	
    while (1) 
    {
		while (PINB & (1 << DATA_PIN));  // Wait for DRDY/DOUT (PB6) to go LOW
		
		_delay_us(1);  // Small delay to ensure stability before clocking
		
		uint32_t data = 0;
		
		for (uint8_t i = 0; i < 20; i++) {  // Read only 20 valid bits
			PORTB |= (1 << SCK_PIN);  // Clock HIGH
			_delay_us(1);  // Ensure propagation delay (50 ns)
			
			data = (data << 1) | ((PINB & (1 << DATA_PIN)) ? 1 : 0);  // Read bit
			
			_delay_us(1);  // Ensure data hold time
			PORTB &= ~(1 << SCK_PIN); // Clock LOW
			_delay_us(1);
		}
		
		// Send 21st clock pulse to force DRDY/DOUT HIGH
		PORTB |= (1 << SCK_PIN);
		_delay_us(1);
		PORTB &= ~(1 << SCK_PIN);
		_delay_us(1);
		
		_delay_us(39);  // Ensure no readback during t_UPDATE (39 µs)
		
		// Convert to signed 20-bit integer
		if (data & 0x80000) {
			data |= 0xFFF00000; // Sign extend to 32-bit int
		}
		
		updateTorque(data);
	}
}
Editor is loading...
Leave a Comment