Hola, ¿como andan? Estoy haciendo un prototipo en el cual utilizo el chip atmega328pb. El esquemático es el siguiente:
Para cargar el bootloader utilicé OptiLoader, con resultado correcto:
OptiLoader Bootstrap programmer.
2011 by Bill Westfield (WestfW)
Target power on! ...
Starting Program Mode [OK]
Reading signature:9516
Searching for image...
Compatible bootloader for ATmega328PB
Found "optiboot_atmega328.hex" for atmega328P
Start address at 7E00
Total bytes read: 502
Setting fuses for programming
Lock: 3F ABE000 Low: FF ABA000 High: DE ABA800 Ext: 5 ABA400
Programming bootloader: 512 bytes at 0x3F00
Commit Page: 3F00:4C3F00
Commit Page: 3F40:4C3F40
Commit Page: 3F80:4C3F80
Commit Page: 3FC0:4C3FC0
Restoring normal fuses
Lock: 2F ABE000
Target power OFF!
Type 'G' or hit RESET for next chip
El problema lo estoy teniendo al momento de programarlo. El código que intento subir es el siguiente:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define dt 5
#define clk 6
#define salida 8
/*Estados del generador de pulsos*/
#define INIT 0
#define PULSE 1
#define IDLE 2
LiquidCrystal_I2C lcd(0x27,16,2);
int estadoActualClk;
int estadoAnteriorClk = digitalRead(clk);
int contador = 0;
int funcion = 5; // default
bool estadoAnterior = true;
byte pulsaciones = 30;
String opciones[]= {"Frec. cardiaca", "Toco"};
/*Variables para timer*/
unsigned int tcnt2;
unsigned int NumSamples = 2;
unsigned int State = INIT;
unsigned int PULSECount = 0;
unsigned int IdleCount = 0;
unsigned long IdlePeriod = 498;
bool comienza = false;
byte flecha[8] = {
B00000,
B00100,
B00010,
B11111,
B00010,
B00100,
B00000,
B00000
};
void setup()
{
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT_PULLUP);
pinMode(salida, OUTPUT);
digitalWrite(salida, LOW);
lcd.createChar(0, flecha);
/** Configuración del Timer2 **/
TIMSK2 &= ~(1<<TOIE2); // Deshabilita las interrupciones por desborde mientras se configura
TCCR2A &= ~((1<<WGM21) | (1<<WGM20)); // Configura el timer2 en modo normal
TCCR2B &= ~(1<<WGM22);
ASSR &= ~(1<<AS2); // Selecciona reloj interno
TIMSK2 &= ~(1<<OCIE2A); // Deshabilita la interrupción por Compare Match A
TCCR2B |= (1<<CS22) | (1<<CS20); // Configura el prescaler para dividir la fcia de reloj en 128
TCCR2B &= ~(1<<CS21);
tcnt2 = 131; // Valor de precarga del contador
TCNT2 = tcnt2; // Carga el timer2
TIMSK2 |= (1<<TOIE2); // Habilita el timer
lcd.setCursor(0,0);
lcd.print("Simulador fetal");
lcd.setCursor(0,1);
lcd.print("C. Tapino 2022");
delay(4000);
lcd.clear();
}
int encoder(){
estadoActualClk = digitalRead(clk);
if(estadoActualClk != estadoAnteriorClk){
lcd.clear();
if(digitalRead(dt) != estadoActualClk){
contador++;
if(contador > 1){
contador = 0;
}
}
else{
contador--;
if(contador < 0){
contador = 1;
}
}
estadoAnteriorClk = estadoActualClk;
}
return contador;
}
void menuPrincipal(int modo){
lcd.setCursor(0, modo);
lcd.write(0);
lcd.setCursor(2, 0);
lcd.print(opciones[0]);
lcd.setCursor(2, 1);
lcd.print(opciones[1]);
}
void menuFcf(int modo){
lcd.setCursor(0, modo);
lcd.write(0);
lcd.setCursor(2, 0);
lcd.print("PPM ");
lcd.setCursor(7, 0);
lcd.print(pulsaciones);
lcd.setCursor(2, 1);
lcd.print("Salir");
}
void subMenuFcf(){
lcd.setCursor(0, 0);
lcd.write(0);
lcd.setCursor(2, 0);
lcd.print("PPM ");
lcd.setCursor(7, 0);
lcd.print(pulsaciones);
lcd.setCursor(2, 1);
lcd.print("Salir");
}
void menuToco(int modo){
lcd.setCursor(0, modo);
lcd.write(0);
lcd.setCursor(2, 0);
lcd.print("No disponible");
lcd.setCursor(2, 1);
lcd.print("Salir");
}
bool pulsador(){
bool estado = (digitalRead(7) == HIGH);
bool result = (estado != estadoAnterior) && estado;
estadoAnterior = estado;
return result;
}
void cambiarPulsaciones(){
unsigned long tiempoAnterior = millis();
while(!pulsador()){
if(millis() - tiempoAnterior > 1000){
subMenuFcf();
tiempoAnterior = millis();
}
estadoActualClk = digitalRead(clk);
if(estadoActualClk != estadoAnteriorClk){
if(digitalRead(dt) != estadoActualClk){
pulsaciones++;
if(pulsaciones > 200){
pulsaciones = 200;
}
}
else{
pulsaciones--;
if(pulsaciones < 30){
pulsaciones = 30;
}
}
if(pulsaciones < 100){
lcd.setCursor(9, 0);
lcd.print(" ");
}
estadoAnteriorClk = estadoActualClk;
}
}
}
void loop(){
switch(funcion){
case 0: // Simulador de latido
comienza = true;
menuFcf(encoder());
if(pulsador()){
if(encoder() == 0){
cambiarPulsaciones();
}
else{
comienza = false;
lcd.clear();
funcion = 5;
}
}
break;
case 1: // Toco no habilitado
menuToco(encoder());
if(pulsador()){
if(encoder() == 1){
lcd.clear();
funcion = 5;
}
}
break;
default:
menuPrincipal(encoder());
if(pulsador()){
if(encoder() == 0){
lcd.clear();
funcion = 0;
}else{
lcd.clear();
funcion = 1;
}
}
break;
}
}
ISR(TIMER2_OVF_vect) {
// recarga el temporizador
TCNT2 = tcnt2;
if(comienza == true){
IdlePeriod = (60000/pulsaciones)-2; // Transformo frecuencia en período y le resto los pulsos en alto (NumSamples -> 2 ms)
switch (State) {
case INIT:
PULSECount = 0;
IdleCount = 0;
State = PULSE;
break;
case PULSE:
digitalWrite(salida, HIGH);
PULSECount++; //inicia el contador PULSECount
if (PULSECount > NumSamples) { //compara el valor contado por PULSECount con el N° de muestras
PULSECount = 0;
digitalWrite(salida, LOW);
State = IDLE;
}
break;
case IDLE:
IdleCount++; //comienza el contador de periodo inactivo
if (IdleCount >= IdlePeriod) { //compara con el valor obtenido en el calculo de IdlePeriod
IdleCount = 0; //si es mayor o igual pone el contador a cero y envía el estado a PULSE
State = PULSE;
}
break;
default:
break;
}
}
}
Para cargar el código estoy utilizando USBasp 2.0, gestor de placas MiniCore (que ya he utilizado antes sin problemas).
El mensaje de error que arroja al intentar cargar el código es el siguiente:
User configuration file is "/home/cris/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : usb
Using Programmer : usbasp
AVR Part : ATmega328PB
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
Programmer Type : usbasp
Description : USBasp, http://www.fischl.de/usbasp/
avrdude: auto set sck period (because given equals null)
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9516 (probably m328pb)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: auto set sck period (because given equals null)
avrdude: reading input file "/tmp/arduino_build_49401/encoder.ino.with_bootloader.hex"
avrdude: writing flash (32768 bytes):
Writing | ################################################## | 100% 2.37s
avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against /tmp/arduino_build_49401/encoder.ino.with_bootloader.hex:
avrdude: load data flash data from input file /tmp/arduino_build_49401/encoder.ino.with_bootloader.hex:
avrdude: input file /tmp/arduino_build_49401/encoder.ino.with_bootloader.hex contains 32768 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 2.02s
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
0x00 != 0x0c
avrdude: verification error; content mismatch
avrdude done. Thank you.
el puerto seleccionado
no existe o tu placa no esta conectada
Por otra parte, intenté cargar el código ejemplo "Blink" con el pin de salida 8, y lo cargó bien, pero al ejecutarlo obtengo un pulso de 25 ms cada 75 ms en lugar de un pulso de 1 segundo cada 1 segundo.
¿Tiene alguien idea de que puede estar sucediendo? ¿Alguna pista de por donde encarar el problema?
