Buscar

Configurando_AD_DA

Prévia do material em texto

USANDO O CONVERSOR A/D DO CORTEX M0 
 
Vamos fazer um passo a passo de como utilizar o conversor A/D do Cortex M0. Inicialmente 
vamos recordar como é o conversor A/D e suas principais características. A figura 1 mostra a 
arquitetura do A/D, o qual é composto de um conversor do tipo SAR de 12 bits, com taxa máxima 
de amostragem de 1MSP/s (um milhão de amostras por segundo). O usuário dispõe de até 16 
entradas analógicas espalhadas pelas portas A, B, C, D e F do microcontrolador. 
 
Figura 1 – Arquitetura do conversor A/D utilizado 
O conversor A/D conta com um circuito de amostragem/retenção (S/H), garantindo estabilidade 
na entrada do conversor A/D. O A/D pode ser utilizado também para medir a Temperatura 
(Temp) do microcontrolador fazendo do mesmo um sensor de temperatura. Também é possível 
medir a tensão de referência do A/D (Vref) e a tensão da bateria que alimenta o circuito de RTC 
(Vbat). Para obter a velocidade máxima de aquisição, um oscilador interno chamado HSI14 de 
14MHz pode ser utilizado. Para a conclusão de uma conversão são necessários 12 pulsos de 
clock. Outros dois são necessários para sincronização do circuito de S/H. Ou seja, utilizando um 
clock de 14MHz é possível obter uma taxa de aquisição de 1MSp/s. 
Como exemplo vamos montar um circuito em que na entrada analógica Ain0 será conectado um 
potenciômetro (ou trimpot) entre o Vcc (3,3 Volts) e o GND (0 Volts). Conectado ao µC temos 
um display de duas linhas por 16 colunas ligado em uma interface de 4 bits. Imprima a leitura 
do conversor (valor absoluto) na primeira linha. Faça a conversão deste valor e imprima o 
mesmo na segunda linha, ambos os valores no canto esquerdo. A figura 2 ilustra o problema. O 
processo de leitura e impressão se repete indefinidamente em intervalos de um segundo! 
 
Figura 2 – Circuito de teste do Conversor A/D 
Iniciamos por configurar os pinos do microcontrolador através da ferramenta STM32 CubeMX. 
A figura 3 mostra a tela de abertura. Clique no menu File e selecione a opção New Project. 
 
Figura 3 – Tela de Abertura – Selecionando a placa do Cortex M0 
Uma janela de diálogo irá surgir. Selecione a aba Board Selector (1). Em Part Number Search (2) 
digite NUCLEO-F072. Na parte inferior da janela irá surgir a placa que você quer utilizar (3). 
Confirme sua escolha clicando duas vezes na figura! 
Uma nova janela de diálogo irá surgir, perguntando se você deseja inicializar (de forma 
automática) os pinos da placa (ver figura 4). Responda que sim! 
 
Figura 4 – Confirmando a Inicialização. 
Então a IDE para configuração do Cortex será aberta, com o desenho da pinagem do µC bem no 
centro (ver figura 5). Os pinos desenhados na cor cinza estão disponíveis para o usuário utilizar. 
Eles estão configurados como GPIO-INPUT do tipo float (condição de Reset - Reset State). Os 
pinos em destaque na cor verde são pinos alocados para a placa NUCLEO e não devem ser nem 
utilizados e nem modificados. Os pinos destacados em laranja são pinos que estão alocados mas 
não estão configurados. Será preciso que o usuário faça a configuração manualmente. Estes 
pinos (PF0 e PF1) são do oscilador externo de alta frequência (>1MHz), cujo cristal não vem 
usualmente soldado na placa. Este oscilador é utilizado no controle da CPU determinando os 
tempos das instruções. Na ausência deste cristal, o oscilador interno HSI toma conta do µC. O 
ideal é soldar um cristal de 8Mhz na placa para exatidão e estabilidade em frequência. 
 
Figura 5 – IDE de configuração do STM32F072. 
Vamos agora escolher o pino do conversor A/D Ain0. Ele está mapeado no pino PA0. Clique no 
pino PA0 e escolha a opção ADC_IN0. O pino muda para cor verde. Precisamos configurar o 
conversor A/D. Clique no menu Analog no canto esquerdo da figura 5. Ele abre um novo menu 
sobre a barra cinza que divide a imagem (ver figura 6). 
 
Figura 6 – Configurando o canal de entrada Ain0. 
Lista de canais usados 
e disponíveis! 
Menu de 
configuração 
Na lista de canais usados e disponíveis pode-se observar que In0 está ocupado (pino PA0). Então 
no menu de configuração vamos configurar este canal analógico. Verifique os seguintes 
parâmetros: 
Clock Prescaler: Asynchronous clock mode 
Resolution: ADC 12-bit 
Data Alignment: Right 
Continous Conversion Mode: Enabled 
End Of Conversion Selection: End of single conversion 
Sampling Time: 1.5 cycles 
External Trigger Source: Launched by software 
Com isto o conversor A/D e a respectiva entrada analógica foram configurados. Agora é 
necessário ir no menu Project Manager (ver figura 7) para ajustar o nome projeto e a IDE que 
será utilizada (Keil uVision5) para editar o programa em linguagem C. 
 
Figura 7 – Definições de Projeto. 
Defina então o nome do seu projeto (o meu defini como F072_AD), onde o mesmo será 
armazenado (no meu caso D:\Workspace\Cube\) e qual a IDE utilizada – MDK-ARMV5. Feito isto 
clique em Generate Code (canto superior direito da tela) para gerar as bibliotecas e o programa 
main.c. O programa leva um certo tempo para gerar toda a estrutura de arquivos. Ao completar 
a tarefa o programa lança a seguinte janela de diálogo (ver figura 8). 
 
Figura 8 – Codificação completada 
Se este processo está sendo feito pela primeira vez ou você abriu apenas o programa Cube (a 
IDE da Keil está fechada), selecione a opção Open Project. Se este processo não está sendo feito 
pela primeira vez (talvez porque você esqueceu de alguma coisa e está corrigindo ou alterando 
alguma configuração) e a IDE da Keil já está aberta, então clique na opção Close. Neste caso, ao 
retornar para a IDE da Keil, uma outra janela de diálogo irá aparecer (ver figura 9). 
 
Figura 9 – Sobrescrever arquivo fonte 
Clique na opção Sim. Duas vezes! 
Agora podemos editar o programa. A IDE da Keil inicia abrindo a Tela de edição vazia, apenas 
indicando no canto esquerdo da janela, a arvore de diretórios criada. Clique no [+] do nome do 
arquivo definido para o projeto. Então o programa desce um nível na arvore de diretórios e 
mostra agora as opções de 4 grandes diretórios. Clique no [+] do diretório Application/User. 
Com isto deve aparecer uma lista de arquivos .c. Selecione o arquivo main.c . Veja na figura 10 
como ficam estes passos. 
 
Figura 10 – Aspecto da IDE da Keil. 
Como o assunto é sobre o conversor A/D, assume-se que as funções do display LCD já foram 
escritas e estão incluídas no arquivo main.c. Logo será discutido apenas as funções do conversor 
A/D. As funções mais básicas são: 
HAL_ADC_Init(&hadc); 
HAL_ADC_Start(&hadc); 
HAL_ADC_PollForConversion(&hadc, 1); 
HAL_ADC_GetValue(&hadc); 
HAL_ADC_Stop(&hadc); 
 
O argumento hadc é uma variável criada pelo Cube para armazenar toda a configuração e 
funcionamento do conversor A/D. A função Init inicializa o conversor A/D. A função Start dispara 
a função de S/H e depois de conversão. A função PollForConversion faz o processador aguardar 
(sincronizar) a resposta do processador com a resposta do A/D. O argumento que segue a 
Janela de Edição da IDE 
variável hadc é o argumento de timeout (em ms), ou seja, o quanto o processador deve aguardar 
até retornar, mesmo que o conversor A/D não tenha dado resposta. Isto é necessário para não 
fazer com que o processador fique travado indefinidamente se o conversor A/D por exemplo, 
apresentar algum tipo de erro. No exemplo, o valor “1” corresponde a 1ms. A função GetValue 
retorna um inteiro que corresponde a resposta do conversor frente a um sinal de entrada. Por 
fim a função Stop encerra o processo de conversão A/D e desativa o circuito. 
Logo, para o exercício proposto, uma solução possível seria da seguinte forma: 
int main(void) 
{ 
 /* USER CODE BEGIN 1 */ 
 int leitura; 
 float x; 
 
 /* USER CODE END 1 */ 
 
 /* MCU Configuration-----------------------------------------*/ 
 
 /* Reset of all peripherals, Initializes the Flash interface */ 
 HAL_Init(); 
 
 /* USER CODE BEGIN Init*/ 
 
 /* USER CODE END Init */ 
 
 /* Configure the system clock */ 
 SystemClock_Config(); 
 
 /* USER CODE BEGIN SysInit */ 
 
 /* USER CODE END SysInit */ 
 
 /* Initialize all configured peripherals */ 
 MX_GPIO_Init(); 
 MX_USART2_UART_Init(); 
 MX_ADC_Init(); 
 /* USER CODE BEGIN 2 */ 
 
 HAL_ADC_Init(&hadc); 
 
 /* USER CODE END 2 */ 
 
 /* Infinite loop */ 
 /* USER CODE BEGIN WHILE */ 
 while (1) 
 { 
 /* USER CODE END WHILE */ 
 
 /* USER CODE BEGIN 3 */ 
 HAL_ADC_Start(&hadc); 
 HAL_ADC_PollForConversion(&hadc, 1); 
 leitura = HAL_ADC_GetValue(&hadc); 
 HAL_ADC_Stop(&hadc); 
 
 x = 0.0008059*leitura; 
 lcd_goto(0, 0); 
 printf("%4d", leitura); 
 lcd_goto(0, 1); 
 printf("%.1f Volts", x); 
 HAL_Delay(925); // Para fazer a leitura a cada 1000 ms... 
 } 
 /* USER CODE END 3 */ 
} 
 
Outro exemplo. Vamos montar um termômetro, conectando na entrada analógica Ain0 um 
sensor de temperatura do tipo LM35, cuja característica de componente é gerar uma saída de 
10mV/°C com offset de 35mV. Conectado ao µC temos um display de duas linhas por 16 colunas 
ligado em uma interface de 4 bits. Imprima seu nome na primeira linha do display. Faça a 
conversão do valor para °C e imprima este valor no canto inferior esquerdo. No canto inferior 
direito imprima a temperatura em °F. A figura 11 ilustra o problema. O termômetro vai ler 
temperaturas entre 0 e 50°C. O processo de leitura e impressão se repete indefinidamente em 
intervalos de 200ms! Imprima o símbolo de grau. Isto pode ser feito imprimindo o caracter 248. 
 
Figura 11 – Termômetro utilizando o Cortex M0. 
 
SOLUÇÃO 
int main(void) 
{ 
 /* USER CODE BEGIN 1 */ 
 int leitura; 
 float Xc, Xf; 
 
 /* USER CODE END 1 */ 
 
 /* MCU Configuration-----------------------------------------*/ 
 
 /* Reset of all peripherals, Initializes the Flash interface */ 
 HAL_Init(); 
 
 /* USER CODE BEGIN Init */ 
 
 /* USER CODE END Init */ 
 
 /* Configure the system clock */ 
 SystemClock_Config(); 
 
 /* USER CODE BEGIN SysInit */ 
 
 /* USER CODE END SysInit */ 
 
 /* Initialize all configured peripherals */ 
 MX_GPIO_Init(); 
 MX_USART2_UART_Init(); 
 MX_ADC_Init(); 
 /* USER CODE BEGIN 2 */ 
 
 HAL_ADC_Init(&hadc); 
 printf("Seu Nome"); 
 
 /* USER CODE END 2 */ 
 
 /* Infinite loop */ 
 /* USER CODE BEGIN WHILE */ 
 while (1) 
 { 
 /* USER CODE END WHILE */ 
 
 /* USER CODE BEGIN 3 */ 
 HAL_ADC_Start(&hadc); 
 HAL_ADC_PollForConversion(&hadc, 1); 
 leitura = HAL_ADC_GetValue(&hadc); 
 HAL_ADC_Stop(&hadc); 
 
 Xc = 0.0806*(leitura-43); 
 Xf = 1.8*Xc + 32; 
 
 lcd_goto(0, 1); 
 printf("%.1f%cC", Xc); 
 lcd_goto(9, 1); 
 printf("%.1f%cF", Xf); 
 HAL_Delay(125); // Para fazer a leitura a cada 200 ms... 
 } 
 /* USER CODE END 3 */ 
} 
 
EXERCÍCIO 
1. Para o problema 2, determine o número efetivo de bits utilizados devido a amplitude do 
sinal fornecida pelo sensor. Projete então um circuito de condicionamento de sinal de modo 
a explorar a totalidade (ou quase a totalidade) dos bits do conversor. Mostre os cálculos 
envolvidos no circuito de condicionamento e no de conversão para a faixa de valores que se 
quer medir (0 a 50°C). Uma vez que o sinal explora mais bits do conversor A/D, determine 
quantas casas decimais podem ser impressas na indicação de °C. 
 
2. Um sensor de temperatura industrial tem saída de 4 a 20mA para a faixa de temperatura de 
-300°C à 850°C. Um resistor de 165Ω é usado para converter a corrente em tensão na 
entrada Ain0. Escreva um programa que imprima na primeira linha o valor absoluto e na 
segunda linha a temperatura em °C. Imprima o resultado com uma casa decimal. Quantas 
casas decimais são válidas nesta solução? 
 
3. Repita o problema 2 indicando quantos bits estão sendo efetivamente utilizados. Projete 
um circuito de condicionamento de sinal que maximize o uso de bits do conversor. 
USANDO O CONVERSOR D/A DO CORTEX M0 
Vamos fazer um passo a passo de como utilizar o conversor D/A do Cortex M0. Inicialmente 
vamos recordar como é o conversor A/D e suas principais características. A figura 12 mostra a 
arquitetura do conversor D/A, de 12 bits. Os Cortex da família M0 podem ter até dois 
conversores independentes, localizados na porta PA4 (DAC1) e PA5 (DAC2) do microcontrolador. 
 
Figura 12 – Conversor D/A 
A tensão de referência é de 3,3Volts. Sabendo isto, utilizando o conversor D/A escreva um 
programa que gere uma tensão contínua de 2,5Volts na porta PA5, usando: 
a) Configuração de 8 bits. Calcule o erro esperado para a saída. 
b) Configuração de 12 bits (a direita). Calcule o erro esperado para a saída. 
c) Configuração de 12 bits (a esquerda). Calcule o erro esperado para a saída. 
Iniciamos por configurar os pinos do microcontrolador através da ferramenta STM32 CubeMX. 
A figura 13 mostra a tela de abertura. Clique no menu File e selecione a opção New Project. Ao 
abrir a janela de diálogo, digite F071 em Part Number Search. 
 
Figura 13 - Tela de Abertura – Selecionando o Cortex STM32F071C8 
Na parte inferior da janela irá surgir o desenho do microcontrolador F071. No canto superior 
direito da janela, confirme sua escolha clicando em Get Start Project. Então a IDE será aberta, 
com o desenho da pinagem do µC bem no centro (ver figura 14). Todos os pinos (exceto os de 
alimentação/sistema) estão desenhados na cor cinza e disponíveis para o usuário utilizar. Eles 
estão configurados como GPIO-INPUT do tipo float (Reset State). Reserve os pinos PC14, PC15, 
PF0, PF1 para os cristais osciladores e PA13 e PA14 para a gravação do dispositivo (Porta DAP). 
Agora vamos configurar as portas do conversor D/A! 
 
Figura 14 – Reservando os pinos do F071 
Clique no menu Analog (em destaque na figura). Ali aparecem as opções ADC, COMP1, COMP2 
e DAC. Clique em DAC. Um novo menu é mostrado, como ilustra a figura 15. 
 
Figura 15 – Configurando os pinos do DAC. 
Clique nos “check boxes” OUT1 e OUT2 (em destaque na figura). Veja que ao fazer isto, os pinos 
PA4 (DAC1) e PA5 (DAC2) foram reservados (mudaram de cor para verde). Na parte debaixo do 
menu Analog ficam as configurações dos DACs. Na opção Trigger escolha a opção software. Com 
isto, ao escrever no registrador do DAC, o valor correspondente em tensão vai aparecer no pino 
de saída deste conversor. 
Agora você deve preencher os dados da aba Project Manager (nome do projeto, onde vai ser 
salvo e que você vai utilizar a ferramenta da Keil – opção MDK-ARMV5). Feito isto clique em 
Generate Code (canto superior direito da janela) para gerar o código e poder editar o programa 
em C. Ao surgir a janela de diálogo, escolha a opção Open Project. 
Vamos resolver o problema então. Para gerar 2,5Volts, determine o valor que deve ser escrito 
em 8bits e 12bits. Para 8 bits, o equacionamento se dá da seguinte forma: 
𝑣𝐷𝐴𝐶 = 𝑉𝑟𝑒𝑓 
𝑛
255
 → 𝑛 = 255
𝑣𝐷𝐴𝐶
𝑉𝑟𝑒𝑓
 → 𝑛 = 193 
O erro para 8 bits equivale a um step do conversor (∆), o qual vale: 
∆ = 
𝑉𝑟𝑒𝑓
28
= ± 6,4𝑚𝑉 
Logo 
𝑣𝐷𝐴𝐶 = 2,5𝑉 ± 6,4𝑚𝑉 
 
Para 12 bits, o equacionamento se dá da seguinte forma: 
𝑣𝐷𝐴𝐶 = 𝑉𝑟𝑒𝑓 
𝑛
4095
 → 𝑛 = 4095
𝑣𝐷𝐴𝐶
𝑉𝑟𝑒𝑓
 → 𝑛 = 3102 
O erro para 12 bits equivale a um step do conversor (∆), o qual vale: 
∆ = 
𝑉𝑟𝑒𝑓
212
= ± 0,4𝑚𝑉 
Logo 
𝑣𝐷𝐴𝐶 = 2,5𝑉 ± 0,4𝑚𝑉 
 
SOLUÇÃO 
int main(void) 
{ 
 /* USER CODE BEGIN 1 */ 
 
 /* USER CODE END 1 */ 
 
 /* MCU Configuration-----------------------------------------*/ 
 
 /* Reset of all peripherals, Initializes the Flash interface */ 
 HAL_Init(); 
 
 /* USER CODE BEGIN Init */ 
 
 /* USER CODE END Init */ 
 
 /* Configure the system clock */ 
 SystemClock_Config(); 
 
 /* USER CODE BEGIN SysInit */ 
 
 /* USER CODE END SysInit */ 
 
 /* Initialize all configured peripherals */ 
 MX_GPIO_Init(); 
 MX_USART2_UART_Init(); 
 MX_DAC_Init(); 
 /* USER CODE BEGIN 2 */HAL_DAC_Init(&hadc); 
 
 // Solução em 8bits... 
 HAL_DAC_Start(&hdac, DAC_CHANNEL_2); 
 HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_8B_R, 193); 
 HAL_DAC_Stop(&hdac, CHANNEL_2); 
 
 // Solução em 12bits... 
 HAL_DAC_Start(&hdac, DAC_CHANNEL_2); 
 HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12_R, 3102); 
 HAL_DAC_Stop(&hdac, CHANNEL_2); 
 
 /* USER CODE END 2 */ 
 
 /* Infinite loop */ 
 /* USER CODE BEGIN WHILE */ 
 while (1) 
 { 
 /* USER CODE END WHILE */ 
 
 /* USER CODE BEGIN 3 */ 
 } 
 /* USER CODE END 3 */ 
} 
 
EXERCÍCIO 
Gere um sinal, conforme ilustra a figura 16, na porta PA4, com resolução de 12 bits. O sinal deve 
ser amostrado no tempo com 101 amostras. O resultado da amostragem deve resultar em um 
sinal de 1kHz. 
 
Figura 16 – Gerador de Sinal dente de serra 
0,000
0,200
0,400
0,600
0,800
Gerador de Sinais
0,5V
0,741V
O valor mais baixo é dado por: 
𝑣𝐷𝐴𝐶 = 3,3 
𝑛
4095
= 0,5𝑉 → 𝑛 = 4095
0,5𝑉
3,3𝑉
 → 𝑛 = 620 
 
O valor mais alto é dado por: 
𝑣𝐷𝐴𝐶 = 3,3 
𝑛
4095
= 0,741𝑉 → 𝑛 = 4095
0,741𝑉
3,3𝑉
 → 𝑛 = 920 
 
Como a sequência vai ter 101 passos a mesma começa com x=0 e termina e termina com x=100. 
Como n começa em 620 e termina em 920, a relação entre x e n pode ser escrita como: 
𝑛 = 620 + 3𝑥 
Para que o sinal tenha frequência de 1kHz (T=1ms), deve-se calcular o tempo de amostragem 
(Ta), o qual depende do número de amostras, ou seja: 
𝑇𝑎 =
𝑇
101
= 
1𝑚𝑠
101
= 9,9𝑢𝑠 
Como não é possível escolher um delay fracionário, devemos fazer uma aproximação. Se 
escolhermos Ta=10us, então: 
𝑇 = 101𝑇𝑎 → 𝑓 = 
1
𝑇
≈ 990𝐻𝑧 
Se escolhermos Ta=9us, então: 
𝑇 = 101𝑇𝑎 → 𝑓 = 
1
𝑇
≈ 1100𝐻𝑧 
Logo, a melhor opção será um tempo de amostragem (Ta) de 10us. Segue a solução em C. 
SOLUÇÃO 
int main(void) 
{ 
 /* USER CODE BEGIN 1 */ 
 int n, x; 
 
 /* USER CODE END 1 */ 
 
 /* MCU Configuration----------------------------------------------*/ 
 
 /* Reset of all peripherals, Initializes the Flash & the Systick. */ 
 HAL_Init(); 
 
 /* USER CODE BEGIN Init */ 
 
 /* USER CODE END Init */ 
 
 /* Configure the system clock */ 
 SystemClock_Config(); 
 
 /* USER CODE BEGIN SysInit */ 
 
 /* USER CODE END SysInit */ 
 
 /* Initialize all configured peripherals */ 
 MX_GPIO_Init(); 
 MX_DAC_Init(); 
 /* USER CODE BEGIN 2 */ 
 
 HAL_DAC_Init(&hdac); 
 
 /* USER CODE END 2 */ 
 
 /* Infinite loop */ 
 /* USER CODE BEGIN WHILE */ 
 while (1) 
 { 
 /* USER CODE END WHILE */ 
 
 /* USER CODE BEGIN 3 */ 
 
 for (x = 0; x < 101; x++) 
 { 
 n = 620 + 3 * x; 
 HAL_DAC_Start(&hdac, DAC_CHANNEL_1); 
 HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, n); 
 HAL_DAC_Stop(&hdac, DAC_CHANNEL_1); 
 delayus(10); 
 } 
 } 
 /* USER CODE END 3 */ 
} 
 
EXERCÍCIO 
Gere um sinal senoidal, conforme ilustra a figura 17, na porta PA5, com resolução de 12 bits. O 
sinal deve ser amostrado no tempo com 256 amostras. O resultado da amostragem deve resultar 
em um sinal de 1kHz. 
 
Figura 17 – Gerador de Sinal dente de serra 
O sinal senoidal apresentado na figura 17 pode ser escrito como: 
𝑠(𝑛) = (0,5(1 + sin (2𝜋
𝑛
256
)))(
4095
3,3
) 
Como a sequência vai ter 256 passos para que o sinal tenha frequência de 1kHz (T=1ms), deve-
se calcular o tempo de amostragem (Ta), ou seja: 
0
200
400
600
800
1000
1200
1400
Gerador Senoidal
0V
1V 
𝑇𝑎 =
𝑇
256
= 
1𝑚𝑠
256
= 3,9𝑢𝑠 
Como não é possível escolher um delay fracionário, devemos fazer uma aproximação. Se 
escolhermos Ta=4us, então: 
𝑇 = 256𝑇𝑎 → 𝑓 = 
1
𝑇
≈ 976𝐻𝑧 
Se escolhermos Ta=3us, então: 
𝑇 = 256𝑇𝑎 → 𝑓 = 
1
𝑇
≈ 1302𝐻𝑧 
Logo, a melhor opção será um tempo de amostragem (Ta) de 4us. Segue a solução em C. 
 
SOLUÇÃO 
/* Private define ------------------------------------------------------------*/ 
/* USER CODE BEGIN PD */ 
// Tabela do sinal senoidal feita em Excel 
const short seno[256] = { 
 620, 636, 651, 666, 681, 696, 711, 726, 741, 756, 771, 
 786, 800, 815, 829, 844 // e assim por diante 
 }; 
 
/* USER CODE END PD */ 
 
int main(void) 
{ 
 /* USER CODE BEGIN 1 */ 
 int n; 
 
 /* USER CODE END 1 */ 
 
 /* MCU Configuration----------------------------------------------*/ 
 
 /* Reset of all peripherals, Initializes the Flash & the Systick. */ 
 HAL_Init(); 
 
 /* USER CODE BEGIN Init */ 
 
 /* USER CODE END Init */ 
 
 /* Configure the system clock */ 
 SystemClock_Config(); 
 
 /* USER CODE BEGIN SysInit */ 
 
 /* USER CODE END SysInit */ 
 
 /* Initialize all configured peripherals */ 
 MX_GPIO_Init(); 
 MX_DAC_Init(); 
 /* USER CODE BEGIN 2 */ 
 
 HAL_DAC_Init(&hdac); 
 
 /* USER CODE END 2 */ 
 
 /* Infinite loop */ 
 /* USER CODE BEGIN WHILE */ 
 while (1) 
 { 
 /* USER CODE END WHILE */ 
 
 /* USER CODE BEGIN 3 */ 
 
 for (n = 0; n < 256; n++) 
 { 
 HAL_DAC_Start(&hdac, DAC_CHANNEL_2); 
 HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, seno[n]); 
 HAL_DAC_Stop(&hdac, DAC_CHANNEL_2); 
 delayus(4); 
 } 
 } 
 /* USER CODE END 3 */ 
}

Continue navegando