[résolu] Fast PWM et prescaler sur attiny85

Bonjour,
j'essaye d'avoir deux pwm sur PB0 et PB1 sur un attiny85.

void setup() {

TCCR0A |= (1<<WGM01) | (1<<WGM00) | (1<<COM0A1) | (1<<COM0B1) | (1<<COM0B0) ;

TCCR0B |=  (1<<CS00) | (1<<CS01);

OCR0A = 63;
OCR0B = 127;

DDRB = 1<<DDB1 | 1<<DDB0;

}

void loop() {

}

ce code me donne bien 2 pwm mais a 63 hz j'ai essayé de changer les valeurs du presacaler
TCCR0B |= (1<<CS00) | (1<<CS01); mis qq soient les valeurs j'ai 63 hz dans le pire cas j'ai plus rien.
pourquoi mystères .... j'ai lu des 10zaines de tuto et d'exemple plus la notice de l'attiny sur les registres mais rien n'y fait.

de plus une des pwm est inversée ....

voilà qu est ce que je n'arrive pas a comprendre ??

merci


DDRB = 1<<DDB1 | 1<<DDB0;
TCCR0A = 0x00;
TCCR0A |=  (1<<WGM00) | (1<<COM0A1) | (1<<COM0B1) | (1<<COM0A0) |(1<<COM0B0) ;
TCCR0B =0x00;
TCCR0B |=  (1<<CS00);

OCR0A = 63;
OCR0B = 127;

2 kHz mais c'est encore insuffisant je voudrais au moins 20 k (inaudible) si possible ...

Bonsoir,

Attiny 85 connais pas, juste atmega328p

20 khz : avec des compteurs 8 bits toutes les fréquences ne sont pas possibles.
Il faut faire le calcul selon le datasheet et prendre la valeur la plus proche ou la plus élevée (datacheet : mieux que les tutos, AMHA).

La première question qui m'est venue à l'esprit : quelle est la valeur réelle de la fréquence horloge ?

Si l'attiny85 est comme les autres avr, en réglage sortie usine, ils sont sur leur oscillateur interne (8 MHz) et un diviseur par 8 est activé pour permettre un test sous pointes simplifié des wafers avant découpe des puces. Soit une fréquence horloge de 1MHz.

La fréquence horloge se règle en configurant les "fuses" qui en réalité sont maintenant une zone particulière d'Eeprom.

hello, c'est confirmé, data sheet page 27

Internal Calibrated RC Oscillator Operating Modes
CKSEL[3:0] Nominal Frequency
0010(1) 8.0 MHz
0011(2) 6.4 MHz
Note:

  1. The device is shipped with this option selected.
  2. This setting will select ATtiny15 Compatibility Mode, where system clock is divided by four, resulting in a 1.6 MHz clock frequency.

édit:
dans ton deuxième code, tu n'es pas en PWM fast
voici un extrait de la data sheet page 73, chaptitre 11.7.3

La modulation de largeur d'impulsion rapide ou le mode PWM rapide (WGM0[2:0] = 3 ou 7) fournit une onde PWM haute fréquence.
option de génération de formulaire. Le PWM rapide diffère de l'autre option PWM par son fonctionnement à pente unique. Le compteur
compte du BAS au HAUT puis recommence du BAS. TOP est défini comme 0xFF lorsque WGM0[2:0] = 3, et
OCR0A lorsque WGM0[2:0] = 7.texte en italique

Bonjour,
après passage de l'horloge a 16 Mhz je suis a 32 kHz
j'ai donc repassé l'attiny en 8 Mz et je suis a 16k ce qui me convient ...

donc en fait il faut systématiquement graver le bootloader sur les attiny vierges en selectionnant 8 ou 16 internal au choix.

merci

Bonjour,

Tu es sur qu'on peut avoir une horloge 16MHz interne?

Oui je viens de le faire choisir 16 Mhz pll et graver l'initialisation. (mais en fait je suis repassé en 8 car 16k c'est inaudible pour la majorité des personnes et moi j'en parle pas ca plonge au dessus de 10k ...)

EDIT: bon par contre j'ai de gros problème avec la fonction millis().

On raconte tout et n'importe quoi certains disent timer0 d'autre timer1 certains réécrivent pour timer1 c'est un gros pot de m...

Non raccourcis trop raccourcissant.

  1. Tous les avr sont concernés
  2. La gravure du bootloader n'a rien a voir avec la configuration des "fuses".
    Arduino entretien la confusion en mélangeant les deux opérations sous le même nom.

La configuration des fuses est obligatoire.
On peut très bien programmer sans bootlaoder en utilisant le même principe (ISCP) que pour graver le bootloader.

Lire la documentation du programme Atmel/Microchip : avrdude.

Programmer avec un bootloader est plus simple, programmer sans bootloader permet de récupérer pour le programme les octets utilisé par le bootloader.

Il ne faut pas dire cela.
Chaque référence de micro Attiny85, atmega328p, etc a ses propres fichiers dans l'IDE arduino.
Les choix sont adaptés au micro, il n'existe pas de solution générale.
Là on discute entre avr, mais c'est largement pire entre différentes architectures : un micro ARM n'a rien à voir avec un micro avr même si Atmel fabrique les deux.

Le juge de paix ce sont les fichiers que tu as téléchargés dans ton IDE arduino pour gérer l'attiny85.
En particulier il existe une fonction nommé init que l'IDE ajoute (dans ton dos) à ton programme ***.ino.
Cette fonction configure le microcontroleur à la "sauce arduino".
La "sauce arduino" est faite pour être la plus passe-partout, elle n'est pas faite pour optimiser. Les micro peuvent faire mieux que la "sauce arduino" mais souvent c'est plus compliqué.

Attention les fonctions de temps (delay, milli, etc ) dépendent directement de la fréquence horloge et du réglage des diviseurs d'horloge du timer fait dans la fonction init().
Si tu as modifié ces réglages, il est normal que ces fonctions retournent des valeurs erronées.

Soit, tu lis les fichiers signalés, soit tu prends un attiny85 vierge, tu charges bootloader "mode" arduino.
Ensuite, tu écris un programme qui t'affiche les valeurs contenues dans tous les registres des timers et pour tous les timers.
Et tu compares les résultats avec ton attiny actuel avec ceux de l'attiny85 vierge.

Tu auras la valeur de tous les diviseurs d'horloge.
L'action pour obtenir un temps correct pourrait bien se limiter à une simple règle de 3.

Bien sur que si dans le sens ou pour flasher les fuses sous arduino ide il faut flasher la séquence init et ceci même sans bootloader. donc on grave bien comme si on avait un bootloader mais sans bootloader
evidemment ça prête a confusion mais je ne suis pas responsable des termes utilisés.
Et dans tout ce qui précède je parle bien d'un attiny sans bootloader même si je l'ai pas explicitement dit a part en utilisant le mot "VIERGES"

Attention les fonctions de temps (delay, milli, etc ) dépendent directement de la fréquence horloge et du réglage des diviseurs d'horloge du timer fait dans la fonction init().

évidemment et je le sais c'est la que le problème se pose car il y a divers avis sur timer0 ou timer1
j'ai réglé le problème en réécrivant une fonction "millisT1()" basée sur le timer1 et évidemment les résultats sont différents de la millis() existante ! je pencherais donc plus pour le timer0 dans la milli() existante ..

encore que en changeant la fréquence processeur et en changeant le timer0 je ne sais pas ce qui a impacter la fonction .. fréquence processeur ou timer0 ou les deux ?

en fait ca règle pas du tout mes problèmes comme je dois mesurer un temps variable de 1ms a 2 ms je dois faire une fonction micros() a peu prés correcte .... c’était plus facile d'essayer de comprendre sur millis() parce que sortir une valeur ok mais sans interface série ... ou alors faut recréer ca de toute piece sans que ca interfère avec les timers ... bonjour l'angoisse

Premier point :
Le bootloader et le réglage des fuses n'ont rien à voir entre eux. Je persiste et signe.
Arduino fait tout en même temps pour que ce soit plus simple pour les utilisateurs, mais ce faisant ne simplifie pas la compréhension.

Deuxiéme point :
La fonction init() n'est pas dans le bootloader.
Arduino ne dit pas que tu écris un programme mais un schetch.
Ce n'est pas pour faire bien, c'est qu'il y a une différence.

Le programme que reçoit le compilateur c'est l'IDE arduino qui l'écrit en ajoutant ce qui manque aux fonctions que tu as écris.

Voilà le VRAI programme "main.cpp" transmis au compilateur : (on le trouve dans les fichiers de l'IDE).

/*
  main.cpp - Main loop for Arduino sketches
  Copyright (c) 2005-2013 Arduino Team.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
	init();

	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

Ce programme répond aux normes du C/C++.
Les fonctions "arduino" sont prédéclarées dans le fichier Arduino.h et tous les registres (Timer, mesure analogique, etc) y sont configurés à la mode Arduino dans la fonction init() qui fait partie de l'IDE Arduino.

Ce que j'ai dis, peut-être n'ai-je pas été clair, c'est de comparer les deux réglages : celui arduino, qui doit donner des valeurs de temps corrects, et ton réglage.

Le réglage des timers c'est une série de diviseurs sur l'horloge système.
Ce que j'ai en tête, c'est que si l'horloge du timer qui gère le temps est égale Fh/128 dans le cas arduino et Fh/16 dans le cas jfs59 et bien @jfs59 quand il veut un temps de 1 seconde ii faudra qu'il en demande 8 fois plus puisque le compteur du timer compte 8 fois plus vite.

Le seul risque que je vois, c'est que les compteurs comptant plus vite, ils déborderont plus vite et on n'aura moins que les 40 ou 50 jours de débordement de la fonction millis().
Je pense qu'il y a de la marge.

J'espère que maintenant que je me suis fais comprendre.
J'espère aussi que je ne me suis pas fichu le doigt dans l'œil jusqu'au coude dans mon raisonnement => même si je pense avoir raison, je n'évacue jamais la possibilité de me tromper.
Ceux qui refusent l'idée qu'ils peuvent se tromper ne font pas de vieux os dans le développement.

Danse l'atmega328p (le seul que je connaisse).
Le Timer 0 est affecté par Arduino pour la mesure de temps.
Ce qui fait que le réglage pour millis impose une fréquence d'environ 900 Hz pour la PWM gérée par T0 et T2 et environ 400 Hz pour les sorties pilotées par T1 qui est 16 bit et qui n'utilise pas le même format de PWM que T0 et T2.

Pour l'attiny85 je ne vois qu'une solution : lire la datasheet.

Question subsidiaire : qui a fait l'adaptation de l'attiny85 à l'IDE Arduino ?
C'est l'équipe Arduino ou c'est une équipe indépendante qui a pu faire des choix différents ?

Donc quand je dis que sous ide arduino il suffit pour changer la fréquence de choisir dans le menu et graver la séquence d'init j'ai tout faux .... ok dont acte

donc calculez les fuses a la main (surtout n'utilisez pas les programmes qui pourraient vous aider ! et utilisez avrdude en ligne de commande ... et surtout pas l'ide arduino qui est une hérésie car ils utilisent pas les bons termes. et tant qu on y est n'utilisez plus non plus l'ide pour programmer il rajoute des trucs dans votre dos et c'est trop facile et ça réduit votre compréhension.

Ou alors il doit y avoir dans l'ide une face cachée ou ca se fait "réglementairement" avec la bonne grammaire mais je dois être c** j'ai pas trouvé. :woozy_face:

Deuxiéme point :
La fonction init() n'est pas dans le bootloader

J'ai beau me relire je ne trouve pas cette affirmation que j'aurais faites .... :face_with_monocle: j'ai pourtant bien cherché

Non, tu as raison.
Lorsqu'on sélectionne 'graver la séquence d’initialisation' l'ide programme les fuses conformément à la fréquence sélectionnée et grave le bootloader (si bootloader il y a).

La fréquence choisie dans le menu doit correspondre à la fréquence réelle, choisie de deux façons possibles :

  • oscillateur interne ou PLL
  • oscillateur externe

Dans les deux cas, modifier le choix dans le menu ne suffira pas à changer la fréquence du microcontrôleur. Les fuses doivent être programmés en conséquence.
Si un oscillateur externe est présent, pour changer de fréquence il faut changer d'oscillateur et reprogrammer les fuses en accord avec la fréquence de l'oscillateur choisi.
Le choix dans le menu Outils sert donc à deux choses :

  • programmer les fuses, ce qui déterminera la vitesse physique
  • indiquer au compilateur quelle fréquence a été choisie, aussi bien pour la compilation du core ARDUINO, des librairies, du bootloader, que celle du sketch

Si par exemple tu utilises un ARDUINO 8MHz et que tu choisis 16MHz dans le menu, si tu ne reprogrammes pas les fuses, les timings (millis, delay, etc.) de ton logiciel seront faux, y compris le baudrate de l'UART.

je le sais bien c'est ce que je fais mais bon quand on choisis de sodomiser des coléoptères en plein vol sans déviation de la trajectoire initiale ....

la encore c'est bien ce que j'ai dis ! on choisis dans le menu et on grave la séquence ce qui programme les fuses. Et je comprends pas pourquoi on fait une tartine de ce truc comme si on avait envie de garder ca secret genre chasse gardée c'est trop facile donc faut surtout pas dire que c'est comme ca ...
et j'ai vérifié avec avrdudess que effectivement les fuses avaient bougés donc je suis sur.

Si j'avais eu envie de me faire une chasse gardée je t'aurais donner la valeur des fuses sans explication afin de me rendre indispensable.

Il me semble que depuis mon inscription en juin 2011 toutes mes interventions sont pour expliquer afin que les demandeurs deviennent autonomes.

J'ai toujours essayé d'aider les demandeurs afin qu'ils trouvent eux même la solution à leur problème, pédagogiquement, c'est la meilleure solution pour les demandeurs.

Je n'ai pas fais de stage au quai d'Orsay et je suis direct et j'appelle un chat un chat.
Si cela déplait à certains tant pis pour eux.

Aller encore un en mode sourdine : super ce mode, on ne voit plus des messages des personnes sélectionnées.

Tu peux en faire de même pour moi, c'est dans les configurations de ton compte.

Adios.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.