This question already has an answer here:
C8051f312 microcontroller [closed]
(1 answer)
Closed 9 years ago.
I have the 8051F312 microcontroller, and I have to turn on the led (on the 7.bit of the P2 port). My code is not working, maybe you have some ideas.
#include < C8051F310.H >
#include < stdio.h >
sbit LED_16 = P2^7; // P2^7-->green LED: 1 = ON; 0 = OFF
void init(void)
{
// XBRN registers_init
XBR1 = 0x40; // Enable the crossbar
PCA0MD &= 0X40; // Disable Watchdog
P2MDOUT |= 0xF0;
ADC0CN = 0x80;
ADC0CF = 0xFC;
REF0CN = 0x08;
}
void main(void)
{
init();
while (1)
{
LED_16 = 1; // LED continuously illuminated
}
}
(sorry for the format, but I had problem with the text editor)
First you need to set input/output to the GPIO. For 8051 micro controller family(According to my knowledge)(I don't know about 8051F312), assigning 1 to a pin sets that gpio as input and assigning 0 sets that gpio as output. So in your case first you need to set P2.7 as output. For that you need to do LED_16 = 0; in your init function. After that you need to consider how your LED is connected to your micro controller pin. If anode of LED connected to micro controller pin you need to make it HIGH to glow the LED. If cathode of LED connected to micro controller pin you need to make it LOW to glow the LED.
If anode of led connected to micro controller your code should be
void main(void)
{
init();
while (1)
{
LED_16 = 1; // LED continuously illuminated
}
}
If cathode of led connected to micro controller, then your code should be
void main(void)
{
init();
while (1)
{
LED_16 = 0; // LED continuously illuminated
}
}
Please find AN101 application note from Silicon Labs. I have compared example source code with your code and I have noticed that:
They use XBR2 = 0x40 for crossbar initialization.
They enable /SYSCLK by XBR1 = 0x80.
They configure output pin to push-pull mode by PRT1CF |= 0x40 (I think it should be PRT1CF |= 0x80 in your case).
Related
I am new to programming. I am working on an esp8266 using it's RTOS SDK. I am trying to make sense of one of it's example code on GPIO use and GPIO interrupts. So from what I have understood the program uses a struct variable to store the various configuration settings of a particular pin or pins. But the source of my confusion is that a single struct variable has been defined for configuring all the pins and the components of input and output pins have been assigned values on the same variable name. Wouldn't the downstream struct component override the previous struct component? The code works fine and still works fine when I defined two different struct variables for input and output.
Please have a look at the code.
gpio_config_t io_conf;
//disable interrupt
io_conf.intr_type = GPIO_INTR_DISABLE;
//set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO15/16
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
//disable pull-down mode
io_conf.pull_down_en = 0;
//disable pull-up mode
io_conf.pull_up_en = 0;
//configure GPIO with the given settings
gpio_config(&io_conf);
//interrupt of rising edge
io_conf.intr_type = GPIO_INTR_POSEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
So my confusion is that shouldn't the io_conf.intr_type = GPIO_INTR_DISABLE be overridden by io_conf.intr_type = GPIO_INTR_POSEDGE and so on?
Here is the complete code. If anybody could help or share some useful link I would be very grateful.
/* gpio example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_system.h"
static const char *TAG = "main";
/**
* Brief:
* This test code shows how to configure gpio and how to use gpio interrupt.
*
* GPIO status:
* GPIO15: output
* GPIO16: output
* GPIO4: input, pulled up, interrupt from rising edge and falling edge
* GPIO5: input, pulled up, interrupt from rising edge.
*
* Test:
* Connect GPIO15 with GPIO4
* Connect GPIO16 with GPIO5
* Generate pulses on GPIO15/16, that triggers interrupt on GPIO4/5
*
*/
#define GPIO_OUTPUT_IO_0 15
#define GPIO_OUTPUT_IO_1 16
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))
#define GPIO_INPUT_IO_0 4
#define GPIO_INPUT_IO_1 5
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))
static xQueueHandle gpio_evt_queue = NULL;
static void gpio_isr_handler(void *arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
static void gpio_task_example(void *arg)
{
uint32_t io_num;
for (;;) {
if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
ESP_LOGI(TAG, "GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
}
}
}
void app_main(void)
{
gpio_config_t io_conf;
//disable interrupt
io_conf.intr_type = GPIO_INTR_DISABLE;
//set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO15/16
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
//disable pull-down mode
io_conf.pull_down_en = 0;
//disable pull-up mode
io_conf.pull_up_en = 0;
//configure GPIO with the given settings
gpio_config(&io_conf);
//interrupt of rising edge
io_conf.intr_type = GPIO_INTR_POSEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//change gpio intrrupt type for one pin
gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
//install gpio isr service
gpio_install_isr_service(0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void *) GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void *) GPIO_INPUT_IO_1);
//remove isr handler for gpio number.
gpio_isr_handler_remove(GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin again
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void *) GPIO_INPUT_IO_0);
int cnt = 0;
while (1) {
ESP_LOGI(TAG, "cnt: %d\n", cnt++);
vTaskDelay(1000 / portTICK_RATE_MS);
gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2);
gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2);
}
}
Please if anybody could help me make sense of this whole code also. Thank you so much in advance!
The below is a code to enable interrupt INT0_vect when PD2 is pressed. The code doesn't ever execute the ISR, but always executes the counter loop from 0 to 9 on the 7 segment in PORT C in the main Function. Also tried the sei(); instead of enabling the I-bit in the SREG. Any ideas?
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define ISR_INT0_PD2 INT0_vect
ISR( ISR_INT0_PD2 ){
PORTC = 0x00;
_delay_ms(100);
}
int main(void)
{
int i=0;
DDRC=0xff; //portc is o/p
PORTC=0x00; // all pins on portc is 0 volt
MCUCR |= (1<<1); // falling edge
GICR |=(1<<6); // enable INT0 set pin6
SREG |=(1<<7); // set GIE pin7
while(1)
{
for(i=0;i<10;i++)
{
PORTC=i;
_delay_ms(1000);
}
}
}
[Below is the screenshot from the simulator I've been using]
For the interrupt to execute you need to call sei() defined in <avr/interrupt.h>.
https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html#gaad5ebd34cb344c26ac87594f79b06b73
EDIT: I was mistaken when I removed the line SREG |= (1 << 7) according to my link that is equivalent to sei(); After I wrote the below example I realized the registers are named differently on the ATMega32, so unfortunately the code below won't run.
Based on the data sheet for an ATMega32 your code should work, have you tried removing the for loop and driving PORTC to logic high (e.g. PORTC = 255)? I noticed when I was writing the code for the ATMega168 that the LED I was using was very dim with the code in your while loop. Also check that INT0 pin is connected via pull-up/pull-down resistor.
This is the code that works on my ATMega168, if I swap the register names to the ones used on the ATMega32 I end up with your code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define ISR_INT0_PD2 INT0_vect
ISR( ISR_INT0_PD2 ){
// If there is a logic change on any pin hold the pins attached to PORTC low for 100ms.
PORTC = 0;
_delay_ms(100);
// Relase PORTC to logic high.
PORTC = 255;
}
int main(void)
{
DDRC = 255; // Set all pins on PORTC to be outputs.
PORTC= 255; // Set all pins on PORTC to be logic high.
EIMSK = 0b00000001; // Set external interupt request enable.
EICRA = 0b00000001; // Set the external interrupt control register A to so that
// any logical change on INT0 generates an interrupt request.
sei(); // Set global interupts enable.
while(1)
{
PORTC=255; // Blink the entire PORTC bank.
_delay_ms(20);
PORTC=0;
_delay_ms(20);
}
}
My Problem is that I have a digital Input initialized on PORTB.0. On that Pin I have a button and a 100k Pull-down Resistor. When I run my Pic with literally nothing ( void main() {while(1){}} ) the Voltage level on this pin works as I want it to (0 to 3.3V). But after I test my programm and initialize as shown in the Code below, it's range goes from 2.8 to 3.3V.
I am using a PIC18LF2520 for my graduation work. I am Programming in MPlab V5.10 with the XC8 1.45 Compiler. I just want an Interrupt for my Button which lies on the RB0 Pin of the uP. The initialisations I made will be shown on the Code down below. I already worked a lot with this particular PIC, but I have never had such an Error before.
void main() {
init();
while(1) {
/*
if(isEXT0Set()) { //If the Button gets pushed
EXT0Int(); //Interrupt Function call
}
*/
}
}
void init() {
//PORT Definitions
TRISA = 0x00;
TRISB = 0xC3;
TRISC = 0x00;
//Oscillator Settings
OSCCON = 0x7F; //8Mhz; Internal Oscillator; INTOSC stable
//Interrupt Settings
INTCON = 0xF0; //Global Enable; Peripherals Enable; TMR0 Enable; INT0 Enable
INTCON2 = 0x64; //INT0 rising Edge; INT1 rising Edge; TMR0 High Priority
INTCON3 = 0x08; //INT1 Enable
ADCON1 = 0x0F; //set all Inputs to Digital ones.
//Timer Settings
T0CON = 0x86; //16-Bit; LtoH; 1/128
T1CON = 0x31; //2 8-Bit; FOSC/4; 1/8
T2CON = 0x07; //Postscaler 1/1; Prescaler 1/16;
TMR0H = 0xE1; //Setting TMR0 to 1 Second
TMR0L = 0x7B;
TMR1IE = 1;
TMR2IE = 0;
}
I expect that when I push the button that INt0IF will be set, but that doesn't happen. I testes it on the Hardware, the result is decribed up above. I hope someone sees what I missed. Thanks in advance. :D
PIC controller has internal pull-up resistors on PORTB and usually, they're much less than 100kOhm. You can turn all of them just changing INTCON2 initialization to:
INTCON2 = 0xE4;
I'm using PIC32MX575F256L microcontroller. This is a simple program to turn on and turn of LED's connected to lower 8 bits of port A using a simple switch as external interrupt:
#include<p32xxxx.h>
#include<plib.h>
void __ISR(3,ipl4) EXTInterrupthandller(void) // interrupt handler
{
PORTAINV = 0x0ff; //toggle lower 8 bits of port A (LEDs)
IFS0CLR = 0x00000800; //clear the interrupt flag
}
main()
{
DDPCONbits.JTAGEN = 0;
TRISA= 0; // set port A as output port
TRISESET = 0x0200; // set external interrupt pin as input pin
PORTA = 0; // initially LEDs are off
IEC0CLR = 0x00000800; // disable INT3
IPC0SET = 0x10000000; // set priority and sub priority of interrupt
INTCONCLR = 0x00000004; // clear the bit for falling edge trigger
IFS0CLR = 0x00000800; // clear the interrupt flag
INTEnableSystemSingleVectoredInt(); // configure system to handle single vector interrupts
IEC0SET = 0x00000800; // enable INT3
while(1); // main loop
}
I'm programming an Intel 8051 (C8051F312) microcontroller. I just want to make a blinking led program by using interrupts. It compiles, but the led does not blink. Any ideas I would appreciate. Thank you!
My code is:
#include <C8051F310.H>
#include <stdio.h>
sbit led = P2^7; //LED connected to D7 of Port2
void timer(void) interrupt 1 //interrupt no. 1 for Timer 0
{
led=~led; // toggle LED on interrupt
TH0=0xFC; // initial values loaded to timer
TL0=0x66;
}
void main(void)
{
TMOD = 0x01; // mode1 of Timer0
TH0 = 0xFC; // initial values loaded to timer
TL0 = 0x66;
EA = 1; // global interrupt enable
ET0 = 1; // enables Timer 0 interrupt
TR0 = 1; // start timer
while(1); // do nothing
}
Like Mike Jablonski above said, you need to knock down your interrupt rate. Your original code is interrupting at 3.0625MHz / 12 / 922 ~= 277Hz. Part of your CKCON addition disables scaling to the timer (by setting T0M), so now you're interrupting at ~3.3kHz. You won't be able to see that.
Seeing anything presumes that you have a functional circuit. You're not configuring your output pin. You said your LED is on "now", but hopefully not meaning that it wasn't before. That wouldn't make a lot of sense since you didn't change anything about what the pin is doing.
Get rid of your CKCON line to keep the /12 scaling, and reload TH0 and TL0 with 0x00 on interrupt. That will get you interrupting at a little less than 4Hz, much more visible.
Make that pin push-pull:
P2MDOUT = 0x80;
XBR1 = 0x40;
Start reading the datasheet to your micro.