i wan't to get Inputs to my Atmega16L from a Button. Ideally i can use the internal Pull-up's, so i don't have to attach them externally.
I've boiled down the code to the minimum:
void main(void) {
// SFIOR &= ~(1<<PUD); // Turn off Pull-up disable
DDRD = 0xFF; // Output PORT D
DDRA = 0x00; // Input PORT A
PORTA = 0xFF; // Pull-up on PORT A
_delay_ms(100);
while (1)
{
if (PINA & (1<<PA1)) // Check if PA0 is High
PORTD |= (1<<PD5); // Set PD5 to High
else
PORTD &= ~(1<<PD5); // Set PD5 to Low
}
return;}
I would expect, the Pin PD5 should be high, because the PA1 is pulled up by the internal pull-up, set on line 6.
But no, when i run the code, the Pin PD5 is low, and i have to connect the Pin PA1 to 5V, in order to get a High Signal on PD5.
Short things Short, it looks like the pull-up isn't active...
If tried working with the SFIOR, but the PUD is disabled by default, as far as i know.
kind regards,
Felix
EDIT: the requested Images:
On the photo you have AVCC power supply not connected (pin 30, against number 11 on the board). AVCC supplies power to ADC and port A. It should be always connected to VCC directly or via a noise filter, but should never be left floating.
Difference between VCC and AVCC should never exceed 0.3 V
Please read the pin descripton at page 5 of the datasheet
Related
Im struggling with the following scenario: I have 2 ESP32 boards (Dev Kit 1) and each ESP32 has 1 MCP23017 I2C module connected to it. So my goal is to use all 16 pins on MCP 1 as Output and all other 16 pins on second MCP as inputs and be able to "READ" these values (HIGH OR LOW) I Already setup connection using common ground on both ESP and wiring SDA SCL accordingly. I Already tested using input and output on same MCP unit and works fine (displays on COM port a seral.println message) but when I want to do the same thing but connecting from MCP1 output pin 1 to MCP2 input pin 1, nothing happens on the COM port, but when I unplug the jumper wire (which I use to connect input pin to output pin on the protoboard) then it does detect the voltage change and displays the message. Any idea whats going on here? Why I cant bridge from 1 MCP output to another MCP input and be able to detect this on COM port? Im using following code:
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp1; // Instantiate mcp module object 1, (MCP001)
int dly = 250; // 1/4 second delay
void setup() {
Wire.begin();
Serial.begin(19200);
Serial.println("MCP module 1 Ready");
mcp1.begin(); // "Start" the mcp object
mcp1.pinMode(0, OUTPUT); //set pin "0" on MCP1 as output
mcp1.pinMode(1, INPUT); //set next pin "1" on MCP1 as input
}
void loop() {
mcp1.digitalWrite(0, HIGH); // Set pin HIGH (on)
if (mcp1.digitalRead (1 == HIGH)) {
Serial.println("Continuity Detected at Pin 1 ");
}
mcp1.digitalWrite(0, LOW); // Set pin LOW (off)
delay(dly); // On for 1/4 second
}
I solved the problem by just removing or commenting out the line 27 (mcp1.digitalWrite(0, LOW);) Now works the way I want. Thanks #romkey for your time and help.
I am trying to connect my TM4C123GH6PM Microcontroller from Texas Instruments with my Smartphone and use it to control an alarm clock and LED Lights. (the LEDs are controlled over a Transistor, which is controlled over an GPIO Pin).
I have some experience with coding in C++ and the TM4C123GH6PM, but I am still learning a lot. So please excuse some foolish mistakes I might have made.
I want to connect the ESP8266 with the Microcontroller using UART and the TivaWare Framework.
I have written some code and my UART works correctly (I tested it by sending chars from UART 4 to 3).
According to the AT commands of ESP8266 It should respond to "AT" with "OK". But whenever I send something to the ESP it responds with exactly what I sent to it. I checked the wiring, and that's not The Issue. Or at least I think so. Please correct me, if the wiring is wrong.
ESP -> TM4C123GH6PM:
GND -> GND
VCC -> 3.3V
Tx -> Rx (UART3 / PC6)
Rx -> Tx (UART4 / PC5)
CH_PD -> 3.3V
I also checked for the power consumption of the ESP. Everything is powered by the USB-port of my laptop, since that helps keep the cable mess down. I monitor the power consumption with (https://www.amazon.de/gp/product/B07C8CM5TG/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1). The ESP is drawing about 150mA from the computer, but the port can provide a lot more. I checked with some LEDs and 400mA is not a problem.
Can anyone help me? I am working on this now for over two days and can't find a Solution. What is the Problem with the ESP not responding correctly to the AT command? The blue light is one, when the code is running.
PS: The attached code contains also code for the alarm clock control and LEDs. I attached it, since it could be part of the problem, but some of it is commented out and most of it is not used.
#include<stdint.h>
#include<stdbool.h>
#include"inc/hw_ints.h"
#include"inc/hw_memmap.h"
#include"inc/hw_types.h"
#include"driverlib/gpio.h"
#include"driverlib/sysctl.h"
#include"driverlib/timer.h"
#include"driverlib/interrupt.h"
#include"driverlib/uart.h"
#include"driverlib/pin_map.h"
#include "driverlib/rom.h"
// stores the time since system start in ms
uint32_t systemTime_ms;
//bools or controling the alarm clock and LEDS
bool an_aus = false;
bool alarm_clock = false;
void InterruptHandlerTimer0A (void)
{
// Clear the timer interrupt flag to avoid calling it up again directly
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// increase the ms counter by 1 ms
systemTime_ms++;
}
void clockSetup(void)
{
uint32_t timerPeriod;
//configure clock
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ| SYSCTL_OSC_MAIN);
//activate peripherals for the timer
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
// configure timers as 32 bit timers in periodic mode
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
// set the variable timerPeriod to the number of periods to generate a timeout every ms
timerPeriod = (SysCtlClockGet()/1000);
// pass the variable timerPeriod to the TIMER-0-A
TimerLoadSet(TIMER0_BASE, TIMER_A, timerPeriod-1);
// register the InterruptHandlerTimer0A function as an interrupt service routine
TimerIntRegister(TIMER0_BASE, TIMER_A, &(InterruptHandlerTimer0A));
// activate the interrupt on TIMER-0-A
IntEnable(INT_TIMER0A);
// generate an interrupt when TIMER-0-A generates a timeout
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// all interrupts are activated
IntMasterEnable();
// start the timer
TimerEnable(TIMER0_BASE, TIMER_A);
}
void UART (void)
{
//configure UART 4:
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART4));
//GPIO pins for transmitting and receiving
GPIOPinConfigure(GPIO_PC4_U4RX);
GPIOPinConfigure(GPIO_PC5_U4TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
//configure UART 8Bit, no parity, baudrat 38400
UARTConfigSetExpClk(UART4_BASE, SysCtlClockGet(), 38400, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
//configure UART 3:
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART3));
GPIOPinConfigure(GPIO_PC6_U3RX);
GPIOPinConfigure(GPIO_PC7_U3TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(), 38400, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
}
void delay_ms(uint32_t waitTime)
{
// Saves the current system time in ms
uint32_t aktuell = systemTime_ms;
// Wait until the current system time corresponds to the sum of the time at the start of the delay and the waiting time
while(aktuell + waitTime > systemTime_ms);
}
void ex_int_handler(void)
{
// press the button to start timer for alarm clock
alarm_clock = true;
GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
}
int main(void)
{
//Peripherals for LED and GPIO
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//UART
UART();
//Timer
clockSetup();
// button
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4);
GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
//OnboardLED
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3);
//Interrupt Timer
GPIOIntDisable(GPIO_PORTF_BASE,GPIO_PIN_4);
GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);
GPIOIntRegister(GPIO_PORTF_BASE,ex_int_handler);
GPIOIntEnable(GPIO_PORTF_BASE,GPIO_PIN_4);
//Transistor Gate
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0);
//GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_0,GPIO_STRENGTH_6MA,GPIO_PIN_TYPE_STD_WPU);
//debugging only: save all the received data from the ESP in an array to look at while debugging
int32_t data[20] = {0};
int32_t j = 0;
//Code for debugging the UART and ESP8266
while(1){
//Checks for Data in the FIFO
while(!UARTCharsAvail(UART4_BASE));
//send AT-command to ESP8266
UARTCharPut(UART4_BASE, 'A');
while(UARTBusy(UART4_BASE));
UARTCharPut(UART4_BASE, 'T');
while(UARTBusy(UART4_BASE));
if(UARTCharsAvail(UART3_BASE))
{
while(UARTCharsAvail(UART3_BASE))
{
//Read data from the FIFO in UART3 -> received from ESP8266
data[j] = UARTCharGet(UART3_BASE);
j++;
}
}
//clear array when its full
if (j >= 20)
{
j = 0;
for(int32_t a = 0; a <21; a++)
{
data[a] = 0;
}
}
}
//code to run the alarm clock and leds
/*
while(1)
{
if (alarm_clock)
{
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,GPIO_PIN_3);
//Wait
delay_ms(30600000);
GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0,GPIO_PIN_0);
alarm_clock = false;
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,0x00);
//Start Red LED blinking when it is finished
while(1)
{
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1);
delay_ms(1000);
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,0x00);
delay_ms(1000);
}
}
}
*/
}
According to the AT commands of ESP8266 It should respond to "AT" with
"OK". But whenever I send something to the ESP it responds with
exactly what I sent to it
Modems with AT Commands commonly ship with the echo mode turned on, so that when you are interacting with it manually through serial port, it will echo the characters you sent first, and then send the reply.
So, when you are automating the process, you first send the characters, then wait for the reply until you reach a '\r'. Well, you are reaching a '\r', but its the one from the echo. You might have some other characters next. You send AT, you should receive AT first, then you have the OK.
To solve this problem, you should turn echo mode off.
The command to turn off echo is ATE0.
I am trying to create NVIC interrupts on the Arduino due. I need 4 external interrupts from push buttons and am having trouble using anything but the NVIC interrupts. First, can I use PMC_PCER0 for all 4 interrupts? Second, can I make multiple interrupts on the same port? Do I enable all interrupts with just one call to NVIC(PIOB_IRQn)? Finally, are there better methods and registers for external interrupts on the Arduino due (sam3x8e).
void configure_ext_int_1(){
PMC->PMC_PCER0 |= 1 << ID_PIOB; // Enable Clock for PIOB - needed for sampling falling edge
PIOB->PIO_PER = PIO_PB27; // Enable IO pin control
PIOB->PIO_ODR = PIO_PB27;
PIOB->PIO_PUER = PIO_PB27; // Enable pull-up
PIOB->PIO_IFER = PIO_PB27; /
PIOB->PIO_DIFSR = PIO_PB27; // Select Debouncing filter
PIOB->PIO_SCDR = 0x4FF; // Set Debouncing clock divider
PIOB->PIO_AIMER = PIO_PB27;
PIOB->PIO_ESR = PIO_PB27;
PIOB->PIO_FELLSR = PIO_PB27;
PIOB->PIO_IER = PIO_PB27;
NVIC_EnableIRQ(PIOB_IRQn);
}
I have elected to use the asf functions available for the SAM3X8E. I am not sure if this will work on all 4 ports simultaneously.
void enable_NVIC_interrupts(){
// PORT A NVIC
pmc_enable_periph_clk(ID_PIOA);
pio_set_input(PIOA, PIO_PA29, PIO_PULLUP;
pio_handler_set(PIOA, ID_PIOC, PIO_PA29, PIO_IT_EDGE, int_RINGMODULATOR);
pio_enable_interrupt(PIOA, PIO_PA29);
NVIC_EnableIRQ(PIOA_IRQn);
// PORT B NVIC
pmc_enable_periph_clk(ID_PIOB);
pio_set_input(PIOB, PIO_PB25, PIO_PULLUP;
pio_handler_set(PIOB, ID_PIOB, PIO_PB25, PIO_IT_EDGE, int_TREMOLO);
pio_enable_interrupt(PIOB, PIO_PB25);
NVIC_EnableIRQ(PIOB_IRQn);
// PORT C NVIC
pmc_enable_periph_clk(ID_PIOC);
pio_set_input(PIOC, PIO_PC22, PIO_PULLUP;
pio_handler_set(PIOC, ID_PIOC, PIO_PC22, PIO_IT_EDGE, int_DISTORTION);
pio_enable_interrupt(PIOC, PIO_PC22);
NVIC_EnableIRQ(PIOC_IRQn);
// PORT D NVIC
pmc_enable_periph_clk(ID_PIOD);
pio_set_input(PIOD, PIO_PD7, PIO_PULLUP;
pio_handler_set(PIOD, ID_PIOD, PIO_PD7, PIO_IT_EDGE, int_REVERB);
pio_enable_interrupt(PIOD, PIO_PD7);
NVIC_EnableIRQ(PIOD_IRQn);
So I have a development board which has some UART peripherals muxed to some tty*-like files.
I have connected some other device on one port (RX pin), and I expect to be able to read the data that it was sent to me.
The devices sends me data in 11-bytes chunks.
This is the code I have been used:
if(-1 == (fd_read = open(port.c_str(), O_RDONLY))) {
throw std::ios_base::failure("Unable to open UART descriptor.");
}
tcgetattr(fd_read, &settings);
/*!
* Set some default settings.
*/
cfsetospeed(&settings, baud); /* baud rate */
settings.c_cflag &= ~PARENB; /* no parity */
settings.c_cflag &= ~CSTOPB; /* 1 stop bit */
settings.c_cflag &= ~CSIZE;
settings.c_cflag |= CS8 | CLOCAL; /* 8 bits */
settings.c_lflag = ICANON; /* canonical mode */
settings.c_oflag &= ~OPOST; /* raw output */
settings.c_cc[VMIN] = 0;
settings.c_cc[VTIME] = 0;
/*!
* Apply the settings for both: the writing and reading file descriptors.
*/
tcsetattr(fd_read, TCSANOW, &settings);
tcflush(fd_read, TCOFLUSH);
The problem is that the other devices sends me a data chunk (I can see it on scope), but the read() function doesn't return.
This is the read function call:
auto bytesReceived = ::read(fd_read, UARTDataBuffer, max_incoming_uart_data_length); // "max_incoming_uart_data_length" is 2048.
The strange thing is that when I use another TX pin from my board, and send the exact the same data (as I suppose to receive from the another device), everything works as expected, the read() function returns with the correct data.
Why is this happening?
L.E. More details about the problem:
Both, the development board (BeagleBone Black) and the other sensor are using 3.3V for UART signals.
After configuring the communication with the code shown above, I also applied the following command on the associated tty*-like file:
stty -F /dev/ttyO2 921600
Where /dev/ttyO2 is my UART-associated port, and 921600 is the baud rate value.
I use this because termios structure don't provide such higher baud values.
I'm expecting that stty won't change the other settings (like parity, start/stop bits, etc), it will only set the baud rate.
Update2: When I open the same port (where I'm expecting data) using minicom, everything works as expected, I'm able to receive data in my application. (and the minicom also captures the data).
I've adjusted the example from here for the STM3240G-EVAL board in order to blink LEDs 3 and 4. I have it working, but am confused by the Mode register setting:
GPIOG->MODER |= (GPIO_MODER_MODER6_0 | GPIO_MODER_MODER8_0) ;
When I read the reference manual (p186), it claims that the mode must be set to 01 for output, yet setting it to 0 in this way works just fine. Ideally I'd like to be able to change to the other modes, but I would have assumed that the above code would have changed pins 6 and 8 of port G to input pins. I must be missing something.
Here's my complete main document in case it's relevant:
#include "stm32f4xx.h"
/* We will use PG6 and PG8 connected to LEDs 1 and 2 because they're the same port. */
/* Find base register value for Port G */
void delay (int a);
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f0xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f0xx.c file
*/
/* GPIOG Periph clock enable */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN;
GPIOG->MODER |= (GPIO_MODER_MODER6_0 | GPIO_MODER_MODER8_0) ;
/* Configure PG6 and PG8 in output mode */
GPIOG->OTYPER &= ~(GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_8) ;
// Ensure push pull mode selected--default
GPIOG->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR6|GPIO_OSPEEDER_OSPEEDR8);
//Ensure maximum speed setting (even though it is unnecessary)
GPIOG->PUPDR &= ~(GPIO_PUPDR_PUPDR6|GPIO_PUPDR_PUPDR8);
//Ensure all pull up pull down resistors are disabled
while (1)
{
/* Set PG6 and PG8 */
/* the bit set/reset low register SETS the output data register */
/* the bit set/reset high register RESETS the output data register */
GPIOG -> BSRRL = (1 << 6);
GPIOG -> BSRRL = (1 << 8);
delay(500000);
/* Reset PC8 and PC9 */
GPIOG -> BSRRH = (1 << 6);
GPIOG -> BSRRH = (1 << 8);
delay(500000);
}
return 0;
}
void delay (int a)
{
volatile int i,j;
for (i=0 ; i < a ; i++)
{
j++;
}
return;
}
You aren't setting it to zero, you're setting it to one.
The definition of the GPIO_MODER_MODER6_0 constant is 0x00001000. The mask for the GPIO_MODER_MODER6 bits is 0x00003000, so you're putting bits 01 into the right place.
If the constant GPIO_MODER_MODER6_0 were defined as zero, then or'ing it into the configuration register would have no effect in any case. To set both bits to zero you'd need to do something like:
GPIOG->MODER &= ~(GPIO_MODER_MODER6_0 | GPIO_MODER_MODER6_1);
The _0 and _1 suffixes refer to the bit numbers for masking, not the values being written.