Atmega32U4 PORTD refuses to read inputs - Page 1
Forum section: electronics / general

author: trini8ed
author_rank: Newbie
timestamp: December 04, 2020, 01:57:48 pm
content: Hello, been working on a propagation delay testing circuit and am having more problems with this atemga32u4 chip. I have setup PORTD in whichever way floating and with input pull-up but cannot seem to get it to detect any change. I have a button on my board to get me in the main while loop in the delay_test() function. Here it spins its wheels just outputting the values on PORTD to the segment but it just always seems to stay at C7 never changes PD1 regardless if I externally apply 5v to that pin. I feel that i'm missing something small here but I appreciate the help thanks.Code:Code:// propagation.c// Bradley Heenk// For Rev 1.0 Board// 11/16/2020// HARDWARE SETUP:// Segments are hooked up// PORTA -------------------------------------------------------------------------------------------------------// PORTA0-7 are connected to the segments of the LED display.// PORTB -------------------------------------------------------------------------------------------------------// PORTB6 goes to the A selector on our 74LVC1G139 decoder for our units LED's// PORTB7 goes to the B selector on our 74LVC1G139 decoder for our units LED's// PORTD -------------------------------------------------------------------------------------------------------// PORTD0 is used as an interrupt to detect when the output signal has propagated through to stop the timer// PORTD1 is used as an interrupt to detect when the relay is latched and starts the timer// PORTD2 is used as an interrupt to detect a button press and turn on the relay// PORTD6 goes to the A selector on our 74LVC1G139 decoder for our segment digit select// PORTD7 goes to the B selector on our 74LVC1G139 decoder for our segment digit select// PORTF & PORTC -----------------------------------------------------------------------------------------------// PORTF0 is used as an output for our segment for A// PORTF1 is used as an output for our segment for B// PORTC6 is used as an output for our segment for C// PORTC7 is used as an output for our segment for D// PORTF4 is used as an output for our segment for E// PORTF5 is used as an output for our segment for F// PORTF6 is used as an output for our segment for G// PORTF7 is used as an output for our segment for DP// pseudo code// 1) Setup the interrupts and port setups// 2) Calibrate the device using SSR2 to get time delay between the two using interrupts// 3) Latch SSR1 to send input signals to external board compare PD0 and PD2 differences// 4) Once latch interrupt is triggered from PD1 stop the timer// 5) Record the time it took for the signal to propagate through// 6) Reset the timer and prepare to disconnect the signal// 7) Start the timer when the relay goes low// 8) Time how long it takes for the signal to drop active low// define statements for booleans#define TRUE 1#define FALSE 0// define statements to decode the segment locations easier#define BLANK 17#define DIGIT_1 3#define DIGIT_2 2#define DIGIT_3 1#define DIGIT_4 0#define DELAY 0#define HOLD 0// define our port locations for our unit and digits#define UNIT_A 6#define UNIT_B 7#define DIG_A 6#define DIG_B 7#define DIG_SEL 6#define DELAY_PIN 5#define HOLD_PIN 4#define TEST_SEL 5// define our custom wire locations#define INT0_PIN 0#define INT1_PIN 1#define INT2_PIN 2#define SSR_PIN 3// define timings of our button presses#define BTN_TIMING 1// library includes#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>// decimal to 7-segment LED display encodings, logic "0" turns on segmentconst uint8_t dec_to_7seg = {0xC0, //0: 8'b1100_00000xF9, //1: 8'b1111_10010xA4, //2: 8'b1010_01000xB0, //3: 8'b1011_00000x99, //4: 8'b1001_10010x92, //5: 8'b1001_00100x82, //6: 8'b1000_00100xF8, //7: 8'b1111_10000x80, //8: 8'b1000_00000x98, //9: 8'b1001_10000x88, //A: 8'b1000_10000x83, //B: 8'b1000_00110xC6, //C: 8'b1100_01100xA1, //D: 8'b1010_00010x86, //E: 8'b1000_01100x8E, //F: 8'b1000_11100xC7, //L: 8'b1100_01110xFF, //off: 8'b1111_1111};// holds data to be sent to the segments. logic zero turns segment onuint8_t segment_data = {0xFF, //off0xFF, //off0xFF, //off0xFF, //off};// define our button press valueuint8_t button = FALSE;uint8_t start = TRUE;uint8_t sel = DELAY;// global counting variableuint32_t countDelay = 0;uint32_t countHold = 0;uint16_t count = 0;//******************************************************************************// chk_buttons// Checks the state of the button number passed to it. It shifts in ones till// the button is pushed. Function returns a 1 only once per debounced button// push so a debounce and toggle function can be implemented at the same time.// Adapted to check all buttons from Ganssel's "Guide to Debouncing"// Expects active low pushbuttons on PINA port. Debounce time is determined by// external loop delay times 12.uint8_t chk_buttons(){// setup our static sates values for button satesstatic uint16_t btnState = 0;const uint8_t status = (!bit_is_clear(PINB, TEST_SEL)); // checks to see if the bit is clearedbtnState = (btnState << 1) | status | 0xE000; // update the stateif (btnState == 0xF000) // check if valid press{// tell main a valid keypress has occurredreturn TRUE;}// check to see which button was pressed return 1 if its the buttonreturn FALSE;}// /*************************************************************************/// // int0 ISR// // When an interrupt is triggered on interrupt 0// /*************************************************************************/// ISR(INT0_vect)// {// } // ISR// /*************************************************************************/// // int1 ISR// // When an interrupt is triggered on interrupt 1// /*************************************************************************/// ISR(INT1_vect)// {// } // ISR// /*************************************************************************/// // int2 ISR// // When an interrupt is triggered on interrupt 2// /*************************************************************************/// ISR(INT2_vect)// {// } // ISR//***********************************************************************************// segment_sum// takes a 16-bit binary input value and places the appropriate equivalent 4 digit// BCD segment code in the array segment_data for display.// array is loaded at exit as: |digit3|digit2|colon|digit1|digit0|void segment_sum(uint16_t sum){// base ten displayuint8_t FACTOR = 16;// do our math to get each of our digitsconst uint8_t ones = sum % FACTOR; // sum % (10 or 16)const uint8_t tens = (sum % (FACTOR * FACTOR)) / FACTOR; // sum % (100 or 256) / (10 or 16)const uint8_t hundreds = (sum % (FACTOR * FACTOR * FACTOR)) / (FACTOR * FACTOR); // sum % (1000 or 4096) / (100 or 256)const uint8_t thosands = sum / (FACTOR * FACTOR * FACTOR); // sum / (1000 or 4096)// segment cases check statementsconst uint8_t four_digits = (sum >= (FACTOR * FACTOR * FACTOR)); // sum >= (1000 or 4096)const uint8_t three_digits = (sum >= (FACTOR * FACTOR)); // sum >= (100 or 256)const uint8_t two_digits = (sum >= FACTOR); // sum >= (10 or 16)// break up decimal sum into 4 digit-segmentssegment_data = dec_to_7seg;if (four_digits){// we are using all 4 digitssegment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;}else if (three_digits){// we are using 2 digitssegment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;}else if (two_digits){// we are using 3 digitssegment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;}else{// we are using 2 digitssegment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;}} // segment_sum//***********************************************************************************//***********************************************************************************//// calculates the hold time before the signal latches off againvoid update_segments(){// bound a counter (0-4) to keep track of digit to displayuint8_t index;for (index = 0x00; index < 4; index++){PORTF = dec_to_7seg;PORTC = dec_to_7seg;// save state of port buint8_t tempB = PORTB;// clear the S0, S1, S2 selector bits and keep temptempB &= !((1 << DIG_A) | (1 << DIG_B));// save our new digit to our combined temp variabletempB |= (index << DIG_SEL);// overwrite portb with our new variablePORTB = tempB;PORTB = tempB;// send 7 segment code to LED segmentsPORTF = segment_data;PORTC = (segment_data << 4);// delay to have the screen get enough power_delay_us(20);}} // calibrate_ssr//***********************************************************************************//***********************************************************************************//// takes in no arguments and compares the difference in startup times between// manufacturing tolerances of the solid state relays being used.void delay_test(){// reset our calibration variables to zero//countDelay = 0;// turn on the solid state relay//PORTD &= ~(1 << SSR_PIN);// spin our wheels until our interrupts are triggeredwhile (TRUE){segment_sum(PORTD);update_segments();}} // calibrate_ssr//***********************************************************************************//***********************************************************************************//// calculates the hold time before the signal latches off againvoid hold_test(){// reset our calibration variables to zerocountHold = 0;// turn off the solid state relayPORTD |= (1 << SSR_PIN);// spin our wheels until we see the signal propagate throughwhile ((PORTD & (1 << PD1)) >> PD1 == 1){countHold++;}} // calibrate_ssr//***********************************************************************************//***********************************************************************************//// calculates the hold time before the signal latches off againuint16_t convert(uint32_t timingCount){return timingCount >> 16;} // calibrate_ssr//***********************************************************************************//***********************************************************************************int main(){// Disable JTAG interfaceMCUCR |= (1 << JTD);MCUCR |= (1 << JTD);// setup our PORTC and PORTF// --------------------------------------// setup PORTF as outputsDDRF = 0xFF;// setup PORTC as outputsDDRC = 0xFF;// setup PORTB// --------------------------------------// select the first digit for our decoderDDRB |= (1 << DIG_A) | (1 << DIG_B);PORTB |= (1 << DIG_A) | (1 << DIG_B);// setup PORTD// --------------------------------------// setup the DDRD for output modeDDRD |= (1 << SSR_PIN) | (1 << HOLD_PIN) | (1 << DELAY_PIN) | (1 << UNIT_A) | (1 << UNIT_B);// setup the interrupt pins in pull-up modePORTD |= (1 << INT0_PIN) | (1 << INT1_PIN) | (1 << INT2_PIN);// setup the pins to select default state of the SSR and unit selectorPORTD |= (1 << UNIT_A) | (1 << UNIT_B) | (1 << SSR_PIN);// setup the interrupt masking//EICRA |= (1 << ISC00) | (1 << ISC01) | (1 << ISC10) | (1 << ISC11) | (1 << ISC20) | (1 << ISC21);//EIMSK |= (1 << INT0) | (1 << INT1) | (1 << INT2);//sei(); // enable interrupts before entering loopwhile (1){uint8_t btnPressed = chk_buttons();// only if the button was pressed overwrite our global variable// this prevents overwritting a successfully button press with a zero// if we do not preform this hard check!if (chk_buttons()){// check to see if we are doing the first test procedureif (start){// update the segments to be blanksegment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;update_segments();// turn on the relays and wait until the signal propagates throughdelay_test();// turn off the relays and get the hold time//hold_test();}else{if (sel == DELAY){sel = HOLD;count = convert(countHold);}else if (sel == HOLD){sel = DELAY;count = convert(countDelay);}}}// break up the disp_value to 4, BCD digits in the array: call (segsum)if (start){segment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;segment_data = dec_to_7seg;}else{segment_sum(count);}update_segments();} // whilereturn 0;} // main

author: Alti
author_rank: Frequent Contributor
timestamp: December 04, 2020, 03:10:30 pm
content: Cross post:https://www.eevblog.com/forum/microcontrollers/atmega32u4-pf4-pf7-always-active-high/

author: trini8ed
author_rank: Newbie
timestamp: December 04, 2020, 03:16:27 pm
content: That post is a separate issue regarding PORTF with JTAG fuses being set. This is a separate issue I'm experiencing regarding PORTD not wanting to take in inputs. JTAG has already been disabled nor shouldn't be related to why PORTD isn't working with inputs.

author: MarkF
author_rank: Super Contributor
timestamp: December 04, 2020, 04:35:55 pm
content: I would suggest you first determine if it is a hardware or software problem.Run a much simpler test program to test the hardware. For example:Code:void main(){while (1) {PORTF = PORTD; // Tie each seven segment to a Port D bit.// Enable Port D pull-ups and jump each bit to GND// then watch for segment to turn ON/OFF.}}

author: trini8ed
author_rank: Newbie
timestamp: December 04, 2020, 06:31:26 pm
content: Yeah I'm thinking its either hardware or another special register I'm missing in the datasheet. I just replaced the Atmega32U4 chip thinking it was that but it did the same thing as always. It always shows FF on the segments as everything is held high but even if I GND any of PORTD it seems to just do nothing still shows FF. I know my segment driver codes work flawless as its been tested and is known working. This means we are left to hardware, schematic wiring, and some magic register that disable PORTD based on some default fuses I missed againCode:int main() {while (1) {DDRD = 0x00; // set portd as inputsPORTD = 0xFF; // setup portd as pullupssegment_sum(PORTD); // output values of portd to segemntsupdate_segments(); // update the segments} // while} // main

author: georges80
author_rank: Frequent Contributor
timestamp: December 04, 2020, 08:33:26 pm
content: PIND is the INPUT pins of port D. Reading PORTD just gives you what you wrote to PORTD (pullup/output register)... FF...cheers,george.

author: trini8ed
author_rank: Newbie
timestamp: December 04, 2020, 08:40:00 pm
content: Bahahahaha yeah oh man figured it was something dumb like that I missed late at night... Yeah go ahead and configure the ports and grab the value I just wrote to you not the inputs of the pins totally intentional