shell脚本之位运算+for循环+返回值承接+shell小数运算

 

用shell脚本实现某个寄存器的某几位设置

 

坑位1:

开发板上不认(ubuntu上可以)

for (( i=0;i<6;i++ ))

do

 

done

换成:

for i in `seq 0 6`

do

 

done

 

坑位2:

返回值承接用#?时默认只截取低8位

setbits  $1 $2 $3 $4
regv=$?
printf "regv= %#x\n" $regv

发现只剩低八位


所以,换种承接方式吧:
 regv=`regread $1`
这种方式是直接将命令执行或在屏幕上输出的东西接过来,是字符串。

 

坑位3:

如上面,reg=`regread $1`得到的字符串若用printf  "%d" 是打印不到的,直接echo才行

 

坑位4:

reg=setbits $1 $2 $3 $4 这种方式来承接会爆语法错误,不是C语言。

 

 坑位5:

$((  ))不支持浮点运算

得用bc 或者awk

 

 

 坑位6:

用awk做小数运算时传入变量做参数要加一堆“‘”

如:

    voltage=`awk 'BEGIN{print ("'"$interger1"'"+0.1*"'"$float1"'")*(1/1024)+0.1 }'`

 

 

 

最终测试成功,如下:

#######################################################                                              
#  test the sar-adc in SOC                                                                           
#######################################################                                              
                                                                                                     
regwrite()                                                                                           
{                                                                                                    
        devmem $1 32 $2                                                                              
}                                                                                                    
                                                                                                     
regread()                                                                                            
{                                                                                                    
        devmem $1                                                                                    
}                                                                                                    
                                                                                                     
##argv[1] :origin data                                                                               
##argv[2] :start bit                                                                                 
##argv[3] :end bit                                                                                   
##argv[4] :result                                                                                    
setbits()                                                                                            
{                                                                                                    
        value=$1                                                                                     
        for i in `seq $2 $3`                                                                         
        do                                                                                           
                mask=$(( 0x1 << $i ))                                                                
                #printf "mask = %#x\n" $mask                                                         
                value=$(( $value & ~$mask ))                                                         
                #printf "clean bit %d value = %#x\n" $i $value                                       
                mask1=$(( 0x1 << ($i - $2) ))                                                        
                #printf "mask1 = %#x\n" $mask1                                                       
                bitv=$(( $4 & mask1 ))                                                               
                #printf "bitv = %#x\n" $bitv                                                         
                value=$(( $value | ($bitv << $2)  ))                                                 
                #printf "set bit %d value = %#x\n" $i $value                                         
        done                                                                                         
                printf "%#x\n" $value                                                                
                return $value                                                                        
}                                                                                                    
                                                                                                     
                                                                                                     
reg_set_bits()                                                                                       
{                                                                                                    
        regv=`regread $1`                                                                            
        regv=`setbits $regv $2 $3 $4 `                                                               
        regwrite $1 $regv                                                                            
}                                                                                                    
                                                                                                     
                                                                                                     
                                                                                                     
reg_set_bits $1 $2 $3 $4   

  

 

 

 

 

 

最终目的:

shell脚本实现adc读取转换结果:

#######################################################                                            
#  test the sar-adc in SOC                                                                         
#######################################################                                            
SAR_ADC_BASE_ADDR=0x03000c6c  
SAR_ADC_REG1_ADDR=$(( $SAR_ADC_BASE_ADDR + 4 ))
SAR_ADC_REG2_ADDR=$(( $SAR_ADC_BASE_ADDR + 8 ))
SAR_ADC_OUT0_ADDR=$(( $SAR_ADC_BASE_ADDR + 0x0C ))
SAR_ADC_OUT1_ADDR=$(( $SAR_ADC_BASE_ADDR + 0X20 ))
SAR_ADC_OUT2_ADDR=$(( $SAR_ADC_BASE_ADDR + 0X24 ))
SAR_ADC_OUT3_ADDR=$(( $SAR_ADC_BASE_ADDR + 0x28 ))

SAR_TURN_ON_REG_ADDR=0x03000e04
SAR_ADC_STATE_REG_ADDR=0x03000c30  

regwrite()                                                                                         
{                                                                                                  
	devmem $1 32 $2                                                                            
}                                                                                                  

regread()                                                                                          
{                                                                                                  
	devmem $1                                                                                  
}                                                                                                  

##argv[1] :origin data                                                                             
##argv[2] :start bit                                                                               
##argv[3] :end bit                                                                                 
##argv[4] :result                                                                                  
setbits()                                                                                          
{                                                                                                  
	value=$1                                                                                   
	for i in `seq $2 $3`                                                                       
	do                                                                                         
		mask=$(( 0x1 << $i ))                                                              
		#printf "mask = %#x\n" $mask                                                       
		value=$(( $value & ~$mask ))                                                       
		#printf "clean bit %d value = %#x\n" $i $value                                     
		mask1=$(( 0x1 << ($i - $2) ))
		#printf "mask1 = %#x\n" $mask1                                                     
		bitv=$(( $4 & mask1 ))                                                             
		#printf "bitv = %#x\n" $bitv                                                       
		value=$(( $value | ($bitv << $2)  ))                                               
		#printf "set bit %d value = %#x\n" $i $value                                       
	done                                                                                       
	printf "%#x\n" $value                                                              
	return $value                                                                      
}                                                                                                  


reg_set_bits()                                                                                     
{                                                                                                  
	regv=`regread $1`                                                                          
	regv=`setbits $regv $2 $3 $4 `                                                             
	regwrite $1 $regv                                                                          
}                                                                                                  

sar_turn_on()
{
	reg_set_bits $SAR_TURN_ON_REG_ADDR 28 28 1
	reg_set_bits $SAR_TURN_ON_REG_ADDR 27 27 1
}

saradc_enable()
{
	reg_set_bits $SAR_ADC_BASE_ADDR 0 0 1  
}                                                                                                     

saradc_disable()
{
	reg_set_bits $SAR_ADC_BASE_ADDR 0 0 0
}

soft_trigger()
{
	if [ $1 -eq 1 ]; then
		reg_set_bits $SAR_ADC_BASE_ADDR 8 8 1
	else
		reg_set_bits $SAR_ADC_BASE_ADDR 8 8 0
	fi
}

#argv[1]: x MHz
set_bauderate()
{
	diver=$(( 40 / $1 ))
	reg_set_bits $SAR_ADC_BASE_ADDR 24 31 $diver
}

#argv[1]: n * bauderate
delay_before_scan()
{
	reg_set_bits $SAR_ADC_REG1_ADDR 0 31 $1
}

#argv[1]: (n+2) * 1/40MHz
delay_before_capture()
{
	reg_set_bits $SAR_ADC_REG2_ADDR 0 15 $1
}

#argv[1]: channel0~channel3 --> bit0~bit3
sarctrl_chsel()
{
	reg_set_bits $SAR_ADC_BASE_ADDR 20 23 $1
}

#argv[1]: sample 2^n times
saradc_cycletimes()
{
	reg_set_bits $SAR_ADC_BASE_ADDR 9 17 $1
}

saradc_init()
{
	sar_turn_on
	saradc_disable
	set_bauderate 10
	delay_before_scan 5
	delay_before_capture 3
	sarctrl_chsel 0x0f
	saradc_cycletimes 1

}

read_ad()
{
	saradc_enable
	soft_trigger 1
	tmp=`regread $SAR_ADC_STATE_REG_ADDR`
	tmp=$(( $tmp & 0x80000000 ))
	timeout=200;
	timeout_flag=0
	while [ $tmp -eq 0 ]
	do
		sleep 0.01
		timeout=$(( $timeout - 1 ))
		if [ $timeout -lt 3 ]; then
			timeout_flag=1
			break;
		fi
	done
	if [ $timeout_flag -eq 0 ]; then

		out0=`regread $SAR_ADC_OUT0_ADDR`
		echo "out0= $out0"
		interger0=$(( $out0 >> 8 ))
		printf "INTERGER0= %d \n" $interger0
		float0=$(( $out0 & 0xff ))
		printf "adc_val0 = 0.1 + ref/2^n * %d.%d =  " $interger0 $float0
		voltage=`awk 'BEGIN{print ("'"$interger0"'"+0.1*"'"$float0"'")*(1/1024)+0.1 }'`
		echo "$voltage V"
		
		#voltage=`bc <<< "scale=4;77.0*(1/1024)+0.1"`
		#echo "= $voltage V"
		out1=`regread $SAR_ADC_OUT1_ADDR`
		interger1=$(( $out1 >> 8 ))
		float1=$(( $out1 & 0xff ))
		printf "adc_val1 = 0.1 + ref/2^n * %d.%d = " $interger1 $float1
		voltage=`awk 'BEGIN{print ("'"$interger1"'"+0.1*"'"$float1"'")*(1/1024)+0.1 }'`
		echo "$voltage V"
		out2=`regread $SAR_ADC_OUT2_ADDR`
		interger2=$(( $out2 >> 8 ))
		float2=$(( $out2 & 0xff ))
		printf "adc_val2 = 0.1 + ref/2^n * %d.%d = " $interger2 $float2
		voltage=`awk 'BEGIN{print ("'"$interger2"'"+0.1*"'"$float2"'")*(1/1024)+0.1 }'`
		echo "$voltage V"
		out3=`regread $SAR_ADC_OUT3_ADDR`
		interger3=$(( $out3 >> 8 ))
		float3=$(( $out3 & 0xff ))
		printf "adc_val3 = 0.1 + ref/2^n * %d.%d = " $interger3 $float3
		voltage=`awk 'BEGIN{print ("'"$interger3"'"+0.1*"'"$float3"'")*(1/1024)+0.1 }'`
		echo "$voltage V"

		echo "note: if output is 0.1V , it maybe lower then 0.1V."
	else
		echo "waite saradc_done flag bit timeout"
	fi
	soft_trigger 0

	saradc_disable
}

saradc_init
read_ad         

 

posted @ 2018-05-25 19:17  云鹤比天  阅读(603)  评论(0编辑  收藏  举报